Mostra o nome do arquivo no início de cada linha ao seguir vários arquivos de uma só vez?

11

quando seguir vários arquivos de uma só vez como mostrado abaixo, existe alguma maneira de mostrar o nome do arquivo no início de cada linha?

tail -f one.log two.log

saída atual

==> one.log <==
contents of one.log here...
contents of one.log here...

==> two.log <==
contents of one.log here...
contents of two.log here..

Procurando por algo como

one.log: contents of one.log here...
one.log: contents of one.log here...
two.log: contents of two.log here...
two.log: contents of two.log here...
    
por mtk 13.04.2015 / 11:44

5 respostas

7

tail  -f ...your-files | 
    awk '/^==> / {a=substr($0, 5, length-8); next}
                 {print a":"$0}'

\ thanks {don_cristti}

    
por 13.04.2015 / 12:50
3

Resposta curta

O GNU Parallel tem um conjunto de boas opções que facilitam muito a realização de tais tarefas:

parallel --tagstring "{}:" --line-buffer tail -f {} ::: one.log two.log

A saída seria:

one.log:	contents of one.log here...
one.log:	contents of one.log here...
two.log:	contents of two.log here...
two.log:	contents of two.log here...

Mais explicações

  • A opção --tagstring=str marca cada linha de saída com a sequência str . Da página de manual parallel :
--tagstring str
                Tag lines with a string. Each output line will be prepended with
                str and TAB (\t). str can contain replacement strings such as {}.

                --tagstring is ignored when using -u, --onall, and --nonall.
  • Todas as ocorrências de {} serão substituídas pelos argumentos do paralela, que, nesse caso, são nomes de arquivos de log; ou seja, one.log e two.log (todos os argumentos após ::: ).

  • A opção --line-buffer é necessária porque a saída de um comando (por exemplo, tail -f one.log ou tail -f two.log ) seria impressa se esse comando fosse concluído. Como tail -f aguardará o crescimento do arquivo, será necessário imprimir a saída na base de linha, o que --line-buffer faz. Novamente na página de manual parallel :

--line-buffer (alpha testing)
                Buffer output on line basis. --group will keep the output
                together for a whole job. --ungroup allows output to mixup with
                half a line coming from one job and half a line coming from
                another job. --line-buffer fits between these two: GNU parallel
                will print a full line, but will allow for mixing lines of
                different jobs.
    
por 16.01.2017 / 15:31
1

Se tail não for obrigatório, você poderá usar grep para conseguir isso:

grep "" *.log

Isto irá imprimir o nome do arquivo como o prefixo de cada linha de saída.

As quebras de saída se *.log se expande para apenas um arquivo. A este respeito:

grep '' /dev/null *.log
    
por 13.04.2015 / 12:12
0

Minha ideia seria criar um único arquivo com registros mesclados de vários arquivos, como alguém sugeriu aqui e prefixar nomes de arquivos:

$ tail -f /var/log/syslog | sed -u -E 's,(^.+$),/var/log/syslog: ,g' >> /tmp/LOG &&
$ tail -f /var/log/Xorg.0.log | sed -u -E 's,(^.+$),/var/log/Xorg.0.log: ,g' >> /tmp/LOG &&
$ tail -f /tmp/LOG
    
por 13.04.2015 / 12:54
0

Algo com xargs e sed poderia funcionar:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
    
por 13.04.2015 / 13:30

Tags