AWK множественный разделитель


у меня есть файл, который содержит следующие строки:

/logs/tc0001/tomcat/tomcat7.1/conf/catalina.properties:app.env.server.name = demo.example.com
/logs/tc0001/tomcat/tomcat7.2/conf/catalina.properties:app.env.server.name = quest.example.com
/logs/tc0001/tomcat/tomcat7.5/conf/catalina.properties:app.env.server.name = www.example.com

в выводе выше я хочу извлечь 3 поля (Номер 2, 4 и последний *.example.com). Я получаю следующий результат:

cat file | awk -F'/' '{print  "t" }'
tc0001   tomcat7.1
tc0001   tomcat7.2
tc0001   tomcat7.5

как мне также извлечь последнее поле с доменным именем, которое находится после '='? Как я могу использовать multiple delimiter для извлечения поля?

6 137

6 ответов:

разделитель может быть регулярным выражением.

awk -F'[/=]' '{print  "\t"  "\t" }' file

выдает:

tc0001   tomcat7.1    demo.example.com  
tc0001   tomcat7.2    quest.example.com  
tc0001   tomcat7.5    www.example.com

хорошая новость! awk разделитель полей может быть регулярное выражение. Вам просто нужно использовать -F"<separator1>|<separator2>|...":

awk -F"/|=" '{print , , $NF}' file

возвращает:

tc0001 tomcat7.1  demo.example.com
tc0001 tomcat7.2  quest.example.com
tc0001 tomcat7.5  www.example.com

здесь:

  • -F="/|=" устанавливает разделитель полей ввода либо / или =. Затем он устанавливает разделитель выходного поля на вкладку.

  • {print , , $NF} печать 3-го, 5-го и последнего поля на основе поля ввода разделитель.


см. другой пример:

$ cat file
hello#how_are_you
i#am_very#well_thank#you

этот файл имеет два разделителя полей, # и _. Если мы хотим напечатать второе поле независимо от того, является ли разделитель одним или другим, давайте сделаем оба разделителя!

$ awk -F"#|_" '{print }' file
how
am

где файлы пронумерованы следующим образом:

hello#how_are_you           i#am_very#well_thank#you
^^^^^ ^^^ ^^^ ^^^           ^ ^^ ^^^^ ^^^^ ^^^^^ ^^^
  1    2   3   4            1  2   3    4    5    6

Если ваш пробел согласован, вы можете использовать его в качестве разделителя, а также вместо вставки \t непосредственно, вы можете установить выходной разделитель, и он будет включен автоматически:

< file awk -v OFS='\t' -v FS='[/ ]' '{print , , $NF}'

Perl one-liner:

perl -F'/[\/=]/' -lane 'print "$F[2]\t$F[4]\t$F[7]"' file

используются следующие параметры командной строки:

  • -n цикл вокруг каждой строки входного файла, поместите строку в $_ переменная, не печатайте автоматически каждую строку

  • -l удаляет новые строки перед обработкой, а затем добавляет их обратно

  • -a режим autosplit-perl автоматически разделит входные линии на @F массив. По умолчанию разбиение на пробелы

  • -F модификатор autosplit, в этом примере разбивается на любой / или =

  • -e выполнить код perl

Perl тесно связан с awk, однако,@F autosplit массив начинается с индекса $F[0] в то время как awk поля начинаются с $1.

для разделителя полей любого числа 2 через 5 и буквы a или # или пространство, где разделяющий символ должен повторяться не менее 2 раз и не более 6 раз, например:

awk -F'[2-5a# ]{2,6}' ...

Я уверен, что вариации этого существуют с помощью () и параметров

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

awk -F"/" '{print " " " " }' sam | sed 's/ cat.* =//g'