Извлечь два поля построчно с несколькими разделителями

Использовать инструмент csvcutиз csvkit:

vmstat 1 1 | tail -2 | tr -s ' ' | csvcut -d ' ' -c free

или

vmstat 1 1 | tail -2 | csvcut -d ' ' -S -c free

1
13.04.2020, 22:36
6 ответов

Попробуйте этот awk:

awk '
{  
    split($0,temp,"definition: ") #Get everything after "definition: " in temp[2]
    split(temp[2],final,";")      #Get everything between "definition :" and ";" in final[1]
    print $2,final[1]
}' 

Один вкладыш по запросу:

awk '{split($0,t,"definition: ");split(t[2],f,";");print $2,f[1]}'
1
28.04.2021, 23:18

Какое-то хакерское предложение:

awk -F'[:;]' '{ print $2,$1 }' file | awk -F' ' '{ print $2, $1 }'

Выход

field01 field05
field11 field15
field21 field25
field31 field35
1
28.04.2021, 23:18

Опоздание на шоу, но другое awkрешение просто для удовольствия

awk -F'[ ;]' '{f=3; while ($f!~"defin") f++; print $2, $(f+1)}' file1
1
28.04.2021, 23:18

На самом деле разделитель полей является регулярным выражением, так что это работает как пример:

awk -F ' definition: |; measure: |; weight: |; wight: |[ :;]+' '{NF=NF};1' file

field01 field02 field03 field04 field05 field06 field07 
field11 field12 field13 field14 field15 field16 
field21 field22 field33 field25 field27 
field31 field32 field03 field34 field35 field36 field47

Я почти уверен, что слово в последней строке является ошибкой, но я включил его, чтобы показать гибкость идеи.

Но учитывая, что все, что вам нужно, это поля 2 и 5. И что количество полей не является стабильным, нам нужно сделать два разбиения, чтобы получить поле 5, и еще одно для поля 2. Первое разбиение разрывает строку в точке definition:, конечная часть разбивается на другие разделители, чтобы получить первое поле (, которое всегда называется field5 (первым послеdefinition). Последнее разбиение на [ ;:]выполняется для получения второго поля:

awk '{split($0,a," definition: "); split(a[2],b,"[ :;]");
      split($0,a,"[ ;:]");
      print a[2],b[1]}
    ' file

field02 field05
field12 field15
field22 field25
field32 field35    
0
28.04.2021, 23:18

Пробовал использовать команду «Нижний», все работает нормально

awk '{for (i=1;i<=NF;i++){if($i ~ /definition:/){gsub(";","",$(i+1));print $2,$(i+1)}}}' filename

выход

field02 field05
field12 field15
field22 field25
field32 field35
0
28.04.2021, 23:18

Я публикую это как отдельный ответ только потому, что это альтернативный взгляд на проблему, и он мне нравится... Не говорю, что это хорошая практика. Мне просто понравилось чередование.... Я думаю, что это красиво.

sed "s/definition: /\n/" file1 | awk -F'[ ;]' '{printf $(NR%2+1)((NR%2==0)?"\n":" ")}'
0
28.04.2021, 23:18

Теги

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