tail -f ...your-files |
awk '/^==> / {a=substr($0, 5, length-8); next}
{print a":"$0}'
\ thanks {don_cristti}
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...
tail -f ...your-files |
awk '/^==> / {a=substr($0, 5, length-8); next}
{print a":"$0}'
\ thanks {don_cristti}
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...
--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.
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
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
Algo com xargs
e sed
poderia funcionar:
$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
Tags tail