Regex para formatar a saída de arquivos

1

Eu tenho um arquivo com o seguinte conteúdo:

   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)

Quero formatá-lo da seguinte maneira: servername e, em seguida, sua velocidade FAN, que está dentro de () bracket

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

Não tenho certeza de como usar isso usando o awk ou qualquer outra ferramenta.

    
por Satish 09.08.2018 / 00:35

6 respostas

2

awk solution

$ 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 solution

Alinha as colunas dinamicamente.

$ 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)
$
    
por 09.08.2018 / 00:44
1
$ 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)

Se você não quiser nenhum espaçamento / alinhamento da segunda coluna, você pode omitir o comando 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)

Se você está lidando com o GNU sed , pode reduzi-lo ainda mais:

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

saídas:

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)

explicação:

  1. em uma linha que contém : , acrescenta a próxima linha ao registro atual.
  2. , em seguida, exclui da nova linha original até o último ( , substitui isso por ( e imprime o registro.
  3. Como perl foi chamado com -n , os registros não afetados não são impressos.

Sed tem uma maneira muito compacta de escrever o mesmo:

sed -ne '/:/N;s/\n.*(/ (/p' input.file
    
por 09.08.2018 / 04:21
0
< file perl -pe 's/\n//g;s/(foo)/\n$1/g' | perl -pe 's/:.*\(/: (/g'
    
por 09.08.2018 / 00:42
0

Usando o awk no modo de parágrafo

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)
    
por 09.08.2018 / 00:40
0
$ 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)

Se não houver espaços ou guias iniciais em cada linha, apenas

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

O script (primeiro) sed anotado (assume -E 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
}
    
por 09.08.2018 / 09:25