一次拖尾多个文件时,在每行开头显示文件名吗?


14

当一次拖尾多个文件时,如下图所示,有什么办法在每行的开头显示文件名吗?

tail -f one.log two.log

电流输出

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

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

寻找类似的东西

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...

您可以查看-vtail 的(详细)选项。这可能不完全符合您的要求,但这只是一个开始。
rahul 2015年

我想multitail可以做到这一点
Gilles'SO-不要再邪恶了''

Answers:


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

\感谢{don_cristti}


@don_crissti,谢谢!(1)一个vs文件-不再给我杯酒!(2)好主意。我开始做这样的事情,但是我懒洋洋地说:“没有人会在文件尾巴-f后面加上空格” :)-我会用你的出色建议。
JJoao 2015年

你能解释长度8吗?为什么这里是8,我知道只有8个作品。
Shicheng Guo

1
尾-n 1 * .txt | awk'/ ^ ==> / {a = substr($ 0,5,length-8); 下一个} {打印一个,$ 1}'| awk'$ 2> 0 {if($ 2!〜/ chrY /)打印$ 1}'| xargs -I {} qsub {}
Guo Shicheng Guo

@ ShichengGuo,8 = length(“ ==>”)+ length(“ <==”)
JJoao

1
您的joojoo魔术awk解决方案令人惊讶/惊奇!
Trevor Boyd Smith,

6

简短答案

GNU Parallel有一组不错的选项,可以很容易地完成这些事情:

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

输出为:

one.log:one.log的内容在这里...
one.log:one.log的内容在这里...
two.log:two.log的内容在这里...
two.log:two.log的内容在这里...

更多说明

  • 该选项--tagstring=str用字符串str标记每条输出行。从parallel 手册页
--tagstring str
                用字符串标记行。每条输出线都将以
                str和TAB(\ t)。str可以包含替换字符串,例如{}。

                使用-u,-onall和--nonall时--tagstring被忽略。
  • 所有出现的{}将被并行参数替换,在这种情况下,并行参数是日志文件名;即one.logtwo.log(之后的所有参数:::)。

  • 该选项--line-buffer是必需的,因为如果该命令完成,则将打印该命令的输出(例如tail -f one.logtail -f two.log)。由于tail -f将等待文件增长,因此需要按行打印输出--line-buffer。再次从parallel 手册页

--line-buffer(alpha测试)
                缓冲输出基于行。--group将保留输出
                一起完成整个工作。--ungroup允许输出与
                半条线来自一份工作,半条线来自
                另一份工作。--line-buffer适合这两者:GNU并行
                将打印整行,但允许混合以下行
                不同的工作。

2

如果tail不是强制性的,则可以使用它grep来实现:

grep "" *.log

这将打印文件名作为每行输出的前缀。

如果*.log仅扩展到一个文件,则输出中断。在这方面:

grep '' /dev/null *.log

我需要在tail -fnot的输出中显示文件名grep
mtk 2015年

@serenesat这只会打印文件的全部内容,不是吗?OP要求指定尾部时打印文件名
rahul 2015年

您也可以执行--with-filename-H始终强制使用文件名前缀。
Trevor Boyd Smith,

我真的很喜欢这个答案!完全可以解决长度为13个字符的解决方案所需的问题。而不是棘手的awk解决方案或未parallel安装的解决方案。
Trevor Boyd Smith,

唯一的问题是,如果您的日志文件的长度为一百万行。那么您的grep将向控制台(或通过ssh)发送100万行垃圾邮件……
Trevor Boyd Smith,

0

我的想法是使用多个文件的合并日志创建一个文件,例如此处建议的人并在文件名前添加:

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

0

可以xargs并且sed可以工作的东西:

$ xargs -I% -P0 sh -c "tail -f % | sed s/^/%:/g" <<EOT
one.log
two.log
EOT
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.