Могу ли я изменить FIELDWIDTHS для каждой строки awk-скрипта?

Это происходит со всеми версиями Satellite (и Foreman ), когда ядро/initramdisk изменяется после выпуска новой ОС и/или после синхронизации репо или загружается неправильно. Мы немного улучшили эту проблему в Foreman 1.20 (Satellite 6.5 ), но она все еще не решена. Предварительное решение было реализовано в Satellite 6.6 (beta )и Foreman 1.22 :https://projects.theforeman.org/issues/26709

.

ВРЕМЕННОЕ РЕШЕНИЕ :Удалите initramdisk/vmlinuz на сервере TFTP и повторно -войдите в режим сборки, чтобы загрузить их.

3
23.04.2021, 15:37
4 ответа

Используя gnu awk, вы можете повторно проанализировать текущую строку, назначив $0 = $0. Например,

echo '1 abcdefghij
2   abcdefghij' |
awk '
/^1/{ FIELDWIDTHS = "1 1 5 5"; $0 = $0; print $3; next }
/^2/{ FIELDWIDTHS = "1 3 3 3"; $0 = $0; print $3; next }
'

Или вы можете рассмотреть более похожее на Unix -решение, передавая данные через один awk, который обрабатывает один формат поля, помечая обработанные строки, например, символом с префиксом #, а затем перенаправляя результат во второй awk.. Например,

awk -v FIELDWIDTHS="1 1 5 5" '
/^1/{ print "#" $3; next }
    { print }
' |
awk -v FIELDWIDTHS="1 3 3 3" '
/^2/{ print $3; next }
/^#/{ print substr($0,2); next }
    { print }
'
3
28.04.2021, 22:51

с любым awk:

awk 'NR%2   { fieldwidths="4 6 5 4 9 2 2 13" } # update fieldwidths on odd line numbers
    !(NR%2) { fieldwidths="4 5 4 2 3 9 7 11" } # update fieldwidths on even line numbers
    # condition { fieldwidths="# # # ..." }   # whatever other condition you want...

{ fields=split(fieldwidths, fldwd); startPos=1;
  for(i=1; i<=fields; i++) {
      printf "%s", (i==1?"": OFS) substr($0, startPos, fldwd[i])
      startPos+=fldwd[i]
  }
  print ""
}' infile
4
28.04.2021, 22:51

Я думаю, что-то вроде этого (использование GNU awk для FIELDWIDTHS )— это то, что вам нужно:

BEGIN {
    type2fw[10] = "7 3 6 8 9"
    type2fw[12] = "5 5 5 5 5 5 5 5 5 5 5"
    type2fw[53] = "1 1 1 17 29 31"
   ....
}
{
    FIELDWIDTHS = type2fw[substr($0,31,2)]
    $0 = $0
    do whatever you like with the fields
}

но это довольно неэффективно, так как выполняется разбиение полей дважды (один раз, когда запись читается, а затем второй раз, когда вы делаете $0=$0 ). Вы могли бы сделать его более эффективным, только повторно -разбивая при изменении типа:

BEGIN {
    type2fw[10] = "7 3 6 8 9"
    type2fw[12] = "5 5 5 5 5 5 5 5 5 5 5"
    type2fw[53] = "1 1 1 17 29 31"
   ....
}
{ type = substr($0,31,2) }
type != prev {
    FIELDWIDTHS = type2fw[type]
    $0 = $0
    prev = type
}
{
    do whatever you like with the fields
}

, и вы можете сначала отсортировать ввод по этому 31-му/32-му полю типа символа (, например. sort -k1.31,1.32 file | awk '...'), поэтому вам нужно изменить FIELDWIDTHS только один раз для каждого типа.

Не видя сжатого, проверяемого многострочного -примера ввода/типа ввода и ожидаемого результата, я не могу быть более конкретным, и это может быть даже неправильный подход, и что-то с использованием match($0,/(foo)(bar)(etc)/,a)или другого подхода было бы лучше.

4
28.04.2021, 22:51

Здесь представлен другой подход, использующий GNU sed с модификатором /eкоманды s///.

Общая идея состоит в том, чтобы хранить разделенный пробелами список ширины полей в файлах, чьи имена — это 31 -32 символа текущей входной записи. Функция unpk получает имя файла, содержащее ширину полей, соответствующую текущей записи. Затем он генерирует код sed, который разрезает текущую запись на основе этой ширины.

#--- edit this function to add the fieldwidths corresponding to
#--- the 2 characters in the 31st/32nd
#--- positions of the input record
_init_() {
  [ -s "$1" ] && return
  case $1 in
    */12) echo '4 6 5 4 9 2 2 13' ;;
    */96) echo '5 5 5 6 7 2 2 13' ;;
  esac > "$1"
}

_unpk_() {
  _init_ "$1"
< "$1" tr -s ' \t' '[\n*]' |
sed -Ee '
  1i\
$!d;H;z;x
  s|.*|s/\\n.{&}/\&\\n/|
  s|$|;s/\\n/ /|
  $a\
s/^.|.$//g
'
}

export -f _init_ _unpk_
tmpdir=$(mktemp -d)

sed -Ee "w $tmpdir/h
  s:.{30}(..).*:_unpk_ '$tmpdir/\\1' | sed -Ef - '$tmpdir/h':e
" file
0
28.04.2021, 22:51

Теги

Похожие вопросы