是否可以在连续流上使用grep?

我的意思是有点像tail-f<file>命令,但输出上有grep,以便只保留我感兴趣的行。

我尝试过tail-f<file>|grep模式,但似乎只有在tail完成后才能执行grep,也就是说永远不会执行。


我一直使用tail-f<file>|grep<pattern>。

它会等到grep刷新,而不是等到它完成(我使用的是Ubuntu)。


是的,这实际上会很好。Grep和大多数Unix命令一次只能对一行流进行操作。每一条从尾部出来的线都会被分析,如果匹配的话就会被传递。


我认为你的问题是grep使用了一些输出缓冲。尝试

tail -f file | stdbuf -o0 grep my_pattern

它将grep的输出缓冲模式设置为无缓冲。


使用BSD grep(FreeBSD、Mac OS X等)时,打开grep的行缓冲模式

tail -f file | grep --line-buffered my_pattern

这看起来像是前一段时间——行缓冲区对于GNUgrep(几乎在任何Linux上都使用)都不重要,因为它在默认情况下被刷新(对于其他Unix类,如SmartOS、AIX或QNX,则为YMMV)。然而,截至2020年11月,需要--行缓冲(至少在openSUSE中使用GNU grep 3.5,但根据下面的评论,似乎通常需要)。


在没有行缓冲选项的地方,使用awk(另一个很棒的bash实用程序)而不是grep!它将不断地从尾部传输数据。

这是如何使用grep的

tail -f <file> | grep pattern

这就是你使用awk的方式

tail -f <file> | awk '/pattern/{print $0}'

在大多数情况下,您可以跟踪-f/var/log/some.log | grep-foo,它会很好地工作。

如果需要在运行的日志文件上使用多个grep,并且发现没有输出,则可能需要将--line缓冲开关插入中间的grep,如下所示:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar

你可以把这个答案看作是增强。。通常我使用

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5

-F在文件旋转的情况下更好(如果文件旋转,-F将无法正常工作)

-A和-B用于在图案出现前后获取线条。。这些块将出现在虚线分隔符之间

但对我来说,我更喜欢做以下事情

tail -F <file> | less

如果您想在流式日志中搜索,这非常有用。我的意思是,回头再向前看


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命令在管道中位于tail之后,因此sed进程id将为$BASHPID+1。


如果你想在整个文件中找到匹配项(而不仅仅是尾部),并且你想让它坐下来等待任何新的匹配项,这很好:

tail -c +0 -f <file> | grep --line-buffered <pattern>

-c+0标志表示输出应该从文件开头(+)开始0字节(-c)。


没有看到任何人为我提供了通常的帮助:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

我更喜欢这样,因为您可以随时使用ctrl+c停止并浏览文件,然后只需按shift+f返回实时流式搜索。


这条命令对我有效(Suse):

mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN  >> logins_to_mail

收集邮件服务的登录信息


你肯定不会成功

tail -f /var/log/foo.log |grep --line-buffered string2search

当您使用“colortail”作为tail的别名时,例如在bash中

alias tail='colortail -n 30'

你可以通过类型别名如果这个输出类似tail是colortail-n30的别名。那你就有你的罪魁祸首了:)

解决方案:

使用删除别名

unalias tail

确保通过此命令使用的是“real”尾部二进制文件

type tail

它应该输出如下内容:

tail is /usr/bin/tail

然后可以运行命令

tail -f foo.log |grep --line-buffered something

祝你好运


在这个问题上,考虑到这类工作是监控工作的重要组成部分,这是我(不那么简短)的回答。。。

使用bash跟踪日志

1.命令尾部

这个命令比在已经发布的答案上读到的要详细一点

手册页中选项tail-f和tail-f之间的区别:-f、 --跟随[={name | descriptor}]随着文件的增长,输出附加数据;...-F与--follow=name相同--重试...--重试如果文件无法访问,则继续尝试打开该文件这意味着:通过使用-F而不是-F,tail将在删除时重新打开文件(例如,在日志旋转时)。这对于多天观察日志文件非常有用。能够同时跟踪多个文件我已经使用过:tail-F/var/www/clients/client*/web*/log/{error,access}.log/var/log/{mail,auth}.log\/var/log/apache2/{,ssl,other_vhosts_}访问日志\/var/log/pure-ftpd/transfer.log通过数百个文件跟踪事件。。。(考虑此答案的其余部分,以了解如何使其可读…;)使用开关-n(不要将-c用于行缓冲!)。默认情况下,尾部将显示最后10行。这可以通过以下方式进行调整:tail-n 0-F文件将跟随文件,但只打印新行tail-n+0-F文件将在跟踪他的进度之前打印整个文件。

2.配管时的缓冲问题:

如果您计划过滤组,请考虑缓冲!请参见sed的-u选项、grep的--line缓冲区或stdbuf命令:

tail -F /some/files | sed -une '/Regular Expression/p'

比在sed命令中不使用-u开关更具反应性(比使用grep效率高得多)。

tail -F /some/files |
    sed -une '/Regular Expression/p' |
    stdbuf -i0 -o0 tee /some/resultfile

3.最近的日志记录系统

在最近的系统上,您必须以几乎相同的方式运行journalctl-xf,而不是tail-f/var/log/syslog。。。

journalctl -axf | sed -une '/Regular Expression/p'

但请阅读手册页,该工具是为日志分析而构建的!

4.将其集成到bash脚本中

两个文件(或更多)的彩色输出下面是一个脚本示例,用于查看许多文件,第一个文件的颜色与其他文件不同:#!/bin/bash尾部-F“$@”|sed-une“/^==>/{h;};//!{Gs/^\\(.*\\)\\n==>.*${1//\//\\\/}.*<==/\\o33[47m\\1\\o33[0m/;s/^\\(.*\\)\\n==>.*<==//\\o33[47;31m\\1\\o33[0m/;p、 }"它们在我的主机上运行良好:苏多/myColoredTail/var/log/{kern.,sys}日志交互式脚本您可能正在查看日志以对事件做出反应?这里有一个小脚本,当一些USB设备出现或消失时播放一些声音,但相同的脚本可以发送邮件或任何其他交互,比如打开咖啡机。。。#!/bin/bashexec{tailF}<<(tail-F/var/log/kern.log)tailPid=$!而:;做read-rsn 1-t.3键盘[“${键盘,}”=“q”]&&中断如果读取-ru$tailF-t 0_;然后read-ru$tailF行case$行*新的\USB\device\found*)播放/some/sound.ogg;;*USB\disconnect*)播放/some/othersound.ogg;;欧洲安全理事会printf“\r%s\e[K”“$line”传真完成回响执行{tailF}<&-杀死$tailPid您可以按Q键退出。