печать после получения всех необходимых полей с помощью awk / sed / bash - PullRequest
0 голосов
/ 31 октября 2018

В поисках правильного способа печати в требуемом формате с помощью awk / sed / bash.

Рассмотрим файл (awk_test.txt) со следующим содержимым,

Checkpoint number: ckpt.123
value1: 10
value2: 10
Checkpoint number: ckpt.234
value1: 20
value2: 25

Как извлечь данные из файла и напечатать их в следующем формате в новой строке?

ckpt.123,10,10
ckpt.234,20,25

Я попытался с помощью следующей команды awk, но не печатает все.

awk < awk_test.txt '/ckpt/{a=$NF} /value1/{b=$NF} /value2/{c=$NF} END {printf "%s,%s,%s\n",a,b,c}'

Ответы [ 4 ]

0 голосов
/ 31 октября 2018

Это может сработать для вас (GNU sed):

sed -r 's/.*: //;N;N;s/\n[^:]*: /,/g' file

Удалите метки и замените новые строки запятыми для строк по модулю три.

0 голосов
/ 31 октября 2018

Для GNU awk, Record Separator RS может быть установлено любое регулярное выражение, в этом случае может быть установлено значение Checkpoint number. Разделитель поля FS может быть установлен на : или \n. Таким образом, строки превращаются в поля.

gawk 'BEGIN{ RS="Checkpoint number" ; FS=": |\n"; OFS="," } { if(NR > 1){ print $2,$4,$6 }}' text.txt

Результат:

ckpt.123,10,10
ckpt.234,20,25

ПРИМЕЧАНИЕ. POSIX поддерживает только один символ в качестве RS. Спасибо @EdMorton и @Rafael за ваши комментарии. Я не привык думать о переносимости.

0 голосов
/ 31 октября 2018
$ awk '/^Check/{if (NR>1) print rec; rec=$NF; next} {rec = rec "," $NF} END{print rec}' file
ckpt.123,10,10
ckpt.234,20,25
0 голосов
/ 31 октября 2018

Вы печатаете данные только в блоке END. Конечно, вам нужен конечный блок, но вам также нужно печатать, когда вы доберетесь до линии ckpt, и там уже накоплены некоторые данные. Это приводит к:

awk '/ckpt/   { if (a != "") printf "%s,%s,%s\n", a, b, c; a = $NF }
     /value1/ { b = $NF }
     /value2/ { c = $NF }
     END      { printf "%s,%s,%s\n", a, b, c }'

, который при использовании данных вашего образца дает:

ckpt.123,10,10
ckpt.234,20,25

Или вы можете даже использовать функцию для инкапсуляции печати:

awk 'function print_it() { printf "%s,%s,%s\n", a, b, c; }
     /ckpt/   { if (a != "") print_it(); a = $NF}
     /value1/ { b = $NF }
     /value2/ { c = $NF }
     END      { print_it() }'

Преимущество заключается в том, что один и тот же код печати используется в обоих местах, где требуется печать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...