Intereting Posts
linux + grub.conf не существует Разрешения каталога по умолчанию для NFS Установите тот же диск на две Linux-машины – SAN / NAS Ускорьте резервное копирование в случае, когда раздел имеет много свободного места Bitmap Font data как массив в C Автоматизация ввода текста из сценария bash без использования EOF Как разделить длинное выражение sed на несколько строк? Установка каталога samba изменяет все права доступа к файлам для пользователя, который его монтировал Использование символической ссылки для точки монтирования Создайте пользователя ssh, который может обращаться только к домашнему каталогу В чем разница в выходе swap -l и swap-памяти, показанной сверху? Имена сетевого интерфейса, выводимые из ifconfig Погрузитесь в исходный код qemu для отслеживания запросов io Как узнать об использовании процессора Intel и GPU в Linux? Потеря данных через ttyACM *, когда для передачи данных используется команда ‘cat’

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

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

foo-6-25.example.com: 1 Var. Speed System Board Normal Yes Normal ( 49) -- foo-5-4.example.com: 1 Var. Speed System Board Normal Yes Normal ( 19) -- foo-8-28.example.com: 1 Var. Speed System Board Normal Yes Normal ( 43) -- foo-9-7.example.com: 1 Var. Speed System Board Normal Yes Normal ( 91) -- foo-5-19.idmz.example.com: 1 Var. Speed System Board Normal Yes Normal ( 19) -- foo-7-3.example.com: 1 Var. Speed System Board Normal Yes Normal ( 20) 

Я хочу отформатировать его следующим образом: имя сервера, а затем его скорость вентилятора, который находится внутри () скобки

 foo-6-25.example.com: ( 49) foo-5-4.example.com: ( 19) 

Не уверен, как использовать это, используя awk или любые другие инструменты.

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) $ 
 $ 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 
 % 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 
 < file perl -pe 's/\n//g;s/(foo)/\n$1/g' | perl -pe 's/:.*\(/: (/g' 

Использование 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) 
 $ 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 }