如何将filter应用于`tail -f`的实时输出?

tail -f path 

以上将立即输出对文件的修改,但是我想对输出应用一个filter,只有在其中存在关键字xxx时才显示。

如何解决这个问题?

使用Unix,您可以将一个程序的输出传送到另一个程序。

所以要过滤尾巴,你可以使用grep:

 tail -f path | grep your-search-filter 

简短的回答: tail -f somefile | grep somepattern tail -f somefile | grep somepattern

但是,这往往不足。 假设你正在拖动一个经常旋转的文件(如果它是一个debugging日志,它可能会被多次旋转)。 在这种情况下, tail -F是你的朋友。 我会让你看看差异。

但是tail -ftail -F打印出一堆行,在这种情况下通常是不希望出现的,所以在这种情况下添加-n0

 tail -F -n0 somefile | grep somepattern 

这样可以,直到你想做其他的过滤,然后你需要小心缓冲。 stdout 在写入terminal时默认是行caching的,但在写入pipe道时是完全caching的。 所以,下面的代码会在发现它们时立即发出行,因为tail是明确的行caching的(或者是在每行的末尾刷新它的输出), grep也是行caching的,因为它的输出是到你的terminal:

 tail -F -n0 somefile | grep somepattern 

但是,你决定使用awkcut类的东西来进一步处理输出。

 tail -F -n0 somefile | grep somepattern | awk '{print $3}' 

而现在你想知道你的输出已经到了哪里去了…取决于日志的数量,你可能会发现你确实得到了输出,但是一次只能成为一个页面,因为现在grep的stdout是以全缓冲方式运行的,所以awk接收4kB的input(默认)。

在这种情况下,可以通过使用--line-buffered选项来告诉grep始终使stdout行被--line-buffered

 tail -F -n0 somefile | grep --line-buffered somepattern | ... 

但是,大多数命令没有模拟--line-buffered 。 在更多脚本化工具的情况下,可以使用一个函数来刷新输出(例如,在awk ,函数是fflush() ,与C对应的名称相同,像Perl和Python这样的工具也有类似的function)。

随着cut喜欢你可能不幸运; …但是你可能会尝试searchunbuffer ,这是我expect工具链提供的东西(我从来没有用过)。

我希望你发现这个有用。

干杯,卡梅隆

你可以使用多个pipe道和greps,并用grep -v排除一些事情,用grep -i等等来区分大小写。

即:tail -100f / var / log / messages | grep -V ACPI | grep -i ata

从尾部开始拖尾100行,并保持拖尾,先用ACPI排除任何行,然后用ata,ATA或其任意组合来显示行。

另一个方便的是ABC选项,用于After,Before和Context(前后的行)行。