跟踪日志文件但仅显示特定行

Ori*_*rev 40 command-line grep

我正在使用 -f 标志跟踪日志文件。然后我将它传递给 grep,以仅查找包含“X”的行。这工作得很好。现在我想再次将它传送到另一个 grep 中,这将删除所有包含“Y”的行。当我添加第二个管道时,文件停止刷新,看起来没有数据到来。

这是有效的命令: tail -f my_file.log | grep "X"

这是没有的命令: tail -f my_file.log | grep "X" | grep -v "Y"

我应该如何构造它以便命令起作用?

hee*_*ayl 54

作为grep缓冲的输出,使用--line-buffered选项grep启用行缓冲:

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'
Run Code Online (Sandbox Code Playgroud)

如果你grep没有这个选项,你可以使用stdbuf作为替代:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'
Run Code Online (Sandbox Code Playgroud)


fed*_*qui 19

我通常发现awk这些类型的逻辑检查更有用:

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this
Run Code Online (Sandbox Code Playgroud)

通过有两个选项卡进行测试,一个是我一直在写的seq 20 >> myfile,另一个是例如tail -f myfile | awk '/3/ && !/13/'.


ter*_*don 15

另一种方法是使用单个grep调用而不是两个调用,从而避免缓冲问题。只需使用正则表达式匹配由 0 个或多个非 Y 字符组成的行,然后是 X,然后是 0 个或多个非 Y 字符,直到行尾”

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
Run Code Online (Sandbox Code Playgroud)