是否可以在连续流上使用 grep ?
grep
我的意思是一种 tail -f <file> 命令,但输出上有 grep ,以便只保留我感兴趣的行 .
tail -f <file>
我已经尝试了 tail -f <file> | grep pattern 但似乎 grep 只能执行 tail 完成,也就是说永远不会 .
tail -f <file> | grep pattern
tail
使用BSD grep(FreeBSD,Mac OS X等)时打开 grep 的行缓冲模式
tail -f file | grep --line-buffered my_pattern
你不需要为GNU grep(在几乎任何Linux上使用)执行此操作,因为它将默认刷新(对于其他类似Unix的喜欢,例如SmartOS,AIX或QNX) .
我一直使用 tail -f <file> | grep <pattern> .
tail -f <file> | grep <pattern>
它将等到grep刷新,直到它完成(我正在使用Ubuntu) .
我认为你的问题是grep使用了一些输出缓冲 . 尝试
tail -f file | stdbuf -o0 grep my_pattern
它会将grep的输出缓冲模式设置为unbuffered .
在大多数情况下,你可以 tail -f /var/log/some.log |grep foo 它会工作得很好 .
tail -f /var/log/some.log |grep foo
如果你需要在正在运行的日志文件中使用多个greps,并且发现没有输出,则可能需要将 --line-buffered 开关粘贴到 middle grep(s)中,如下所示:
--line-buffered
tail -f /var/log/some.log | grep --line-buffered foo | grep bar
如果你想在整个文件中找到匹配项(而不仅仅是尾部),并且你希望它能够等待任何新的匹配,那么这很有效:
tail -c +0 -f <file> | grep --line-buffered <pattern>
-c +0 标志表示输出应该从文件的开头( + )开始 0 个字节( -c ) .
-c +0
+
0
-c
没有看到任何人提供我通常的目的:
less +F <file> ctrl + c /<search term> <enter> shift + f
我更喜欢这个,因为您可以使用 ctrl + c 停止并在文件中导航,然后只需按 shift + f 返回实时流式搜索 .
ctrl + c
shift + f
sed 将是正确的命令(流编辑器)
tail -n0 -f <file> | sed -n '/search string/p'
然后,如果您希望tail命令在找到特定字符串后退出:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
显然是一种基础:$ BASHPID将是tail命令的进程ID . sed命令紧接在管道尾部之后,因此sed进程id将为$ BASHPID 1 .
您可以将此答案视为增强...通常我正在使用
tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5
文件旋转时-F更好(如果文件旋转,-f将无法正常工作)
-A和-B对于在模式出现之前和之后获取行很有用..这些块将出现在虚线分隔符之间
是的,这实际上可以正常工作 . Grep 并且大多数Unix命令一次一行地在流上运行 . 从尾部出来的每一行都将被分析并传递,如果匹配的话 .
Grep
这一个命令适合我(Suse):
mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN >> logins_to_mail
收集登录邮件服务
使用awk(另一个很棒的bash实用程序)而不是grep,你没有行缓冲选项!它会不断地从尾部流式传输数据 .
这就是你如何使用grep
这就是你如何使用awk
tail -f <file> | awk '/pattern/{print $0}'
11 回答
使用BSD grep(FreeBSD,Mac OS X等)时打开
grep
的行缓冲模式你不需要为GNU grep(在几乎任何Linux上使用)执行此操作,因为它将默认刷新(对于其他类似Unix的喜欢,例如SmartOS,AIX或QNX) .
我一直使用
tail -f <file> | grep <pattern>
.它将等到grep刷新,直到它完成(我正在使用Ubuntu) .
我认为你的问题是grep使用了一些输出缓冲 . 尝试
它会将grep的输出缓冲模式设置为unbuffered .
在大多数情况下,你可以
tail -f /var/log/some.log |grep foo
它会工作得很好 .如果你需要在正在运行的日志文件中使用多个greps,并且发现没有输出,则可能需要将
--line-buffered
开关粘贴到 middle grep(s)中,如下所示:如果你想在整个文件中找到匹配项(而不仅仅是尾部),并且你希望它能够等待任何新的匹配,那么这很有效:
-c +0
标志表示输出应该从文件的开头(+
)开始0
个字节(-c
) .没有看到任何人提供我通常的目的:
我更喜欢这个,因为您可以使用
ctrl + c
停止并在文件中导航,然后只需按shift + f
返回实时流式搜索 .sed 将是正确的命令(流编辑器)
tail -n0 -f <file> | sed -n '/search string/p'
然后,如果您希望tail命令在找到特定字符串后退出:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
显然是一种基础:$ BASHPID将是tail命令的进程ID . sed命令紧接在管道尾部之后,因此sed进程id将为$ BASHPID 1 .
您可以将此答案视为增强...通常我正在使用
文件旋转时-F更好(如果文件旋转,-f将无法正常工作)
-A和-B对于在模式出现之前和之后获取行很有用..这些块将出现在虚线分隔符之间
是的,这实际上可以正常工作 .
Grep
并且大多数Unix命令一次一行地在流上运行 . 从尾部出来的每一行都将被分析并传递,如果匹配的话 .这一个命令适合我(Suse):
收集登录邮件服务
使用awk(另一个很棒的bash实用程序)而不是grep,你没有行缓冲选项!它会不断地从尾部流式传输数据 .
这就是你如何使用grep
这就是你如何使用awk