我用 -f 标志跟踪日志文件。然后我将其通过管道传输到 grep,以仅查找包含“X”的行。这工作得很好。现在我想再次将其通过管道传输到另一个 grep,这将删除所有包含“Y”的行。当我添加第二个管道时,文件停止刷新,看起来没有数据传入。
这是有效的命令: tail -f my_file.log | grep "X"
这是不执行以下功能的命令: tail -f my_file.log | grep "X" | grep -v "Y"
我应该如何构造它才能使命令正常工作?
答案1
由于的输出grep
是缓冲的,因此使用--line-buffered
选项grep
来启用行缓冲:
tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'
如果你grep
没有该选项,你可以使用stdbuf
以下替代方案:
tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'
答案2
我通常发现awk
这些类型的逻辑检查更有用:
tail -f /path/to/log | awk '/X/ && !/Y/'
# ^^^ ^^^^
# this I want but not this
通过两个标签进行测试,一个标签中我继续书写seq 20 >> myfile
,另一个标签中例如tail -f myfile | awk '/3/ && !/13/'
。
答案3
另一种方法是使用单个grep
调用而不是两个,这样可以避免缓冲问题。只需使用一个正则表达式来匹配由 0 个或多个非 Y 字符组成的行,然后是 X,然后是 0 个或多个非 Y,直到行尾”
tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'