Regex для форматирования вывода файлов

Прежде всего, в начале команды cat нет необходимости.Вы можете перенаправить вывод файла в awk, используя "

awk -F"|" '{
  printf "%s", $1;
  for (i=2; i<=NF; i++) {
    if (match($i, /\[(.*?)>/)) {
      printf " %s", substr($i,RSTART,RLENGTH);
  }};
  printf "\n"
}' x.txt

Для каждой строки в файле печатается первое поле, за которым следуют все совпадения регулярных выражений, найденные в каждом из оставшихся полей (если есть). Поля вывода разделены пробелами; это можно изменить, отредактировав начальный пробел во второй команде printf.

1
09.08.2018, 02:15
6 ответов

Использование awk в режиме абзаца

awk -vRS='\n[ \t]*--' '
  match($0, /\( *[0-9]+\)/) {print $1, substr($0,RSTART,RLENGTH)}
' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)
0
27.01.2020, 23:18
< file perl -pe 's/\n//g;s/(foo)/\n$1/g' | perl -pe 's/:.*\(/: (/g'
0
27.01.2020, 23:18

awk решение

$ awk '/:/{d=$1}/Speed/{printf"%-28s%s\n",d,substr($0,length($0)-4)}' file
foo-6-25.example.com:       ( 49)
foo-5-4.example.com:        ( 19)
foo-8-28.example.com:       ( 43)
foo-9-7.example.com:        ( 91)
foo-5-19.idmz.example.com:  ( 19)
foo-7-3.example.com:        ( 20)
$

awk+ columnраствор

Динамическое выравнивание столбцов.

$ awk '/:/{d=$1}/Speed/{print d,substr($0,length($0)-4)}' file|column -to' '
foo-6-25.example.com:       ( 49)
foo-5-4.example.com:        ( 19)
foo-8-28.example.com:       ( 43)
foo-9-7.example.com:        ( 91)
foo-5-19.idmz.example.com:  ( 19)
foo-7-3.example.com:        ( 20)
$
2
27.01.2020, 23:18
$ sed -e '/--/d;N;s/\n/ /;s/[[:blank:]]\+//;s/[[:blank:]]\+[^(]\+/, /' file | column -ts ','
foo-6-25.example.com:        ( 49)
foo-5-4.example.com:         ( 19)
foo-8-28.example.com:        ( 43)
foo-9-7.example.com:         ( 91)
foo-5-19.idmz.example.com:   ( 19)
foo-7-3.example.com:         ( 20)

Если вам не нужны интервалы/выравнивание 2-го столбца, вы можете пропустить команду column:

$ sed -e '/--/d;N;s/\n/ /;s/[[:blank:]]\+//;s/[[:blank:]]\+[^(]\+/ /' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

Если вы имеете дело с GNU sed, вы можете уменьшить его еще больше:

$ sed -e '/--/d;N;s/\n/ /;s/[ ]\+//;s/[ ]\+[^(]\+/ /' file
1
27.01.2020, 23:18
% perl -ne 'print(($_.= <>) =~ s/\n.*\(/ (/r) if /:/' input.file

выходы:

foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

объяснение:

  1. в строке, содержащей :, он добавляет следующую строку к текущей записи.
  2. затем удаляет новую строку исходной строки до последней (, заменяет ее на (и печатает запись.
  3. Поскольку perlвызывается с помощью -n, незатронутые записи не печатаются.

Sedимеет очень компактный способ записи того же:

sed -ne '/:/N;s/\n.*(/ (/p' input.file
1
27.01.2020, 23:18
$ sed -nE '/:/{N;s/^[[:space:]]+//; s/:[^(]+/: /p;}' file
foo-6-25.example.com: ( 49)
foo-5-4.example.com: ( 19)
foo-8-28.example.com: ( 43)
foo-9-7.example.com: ( 91)
foo-5-19.idmz.example.com: ( 19)
foo-7-3.example.com: ( 20)

Если в каждой строке нет начальных пробелов или табуляции, то просто

sed -nE '/:/{N;s/:[^(]+/: /p;}' file

(первый)sedскрипт с аннотациями (предполагает -Eи-n):

/:/{                    # this line contains a host name
    N;                  # append the next line from the input
    s/^[[:space:]]+//;  # remove the initial spaces or tabs
    s/:[^(]+/: /p;      # remove the bit between the ":" and "(" and print
}
0
27.01.2020, 23:18

Теги

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