Linux 如何';grep';连续的溪流?

Linux 如何';grep';连续的溪流?,linux,bash,shell,grep,tail,Linux,Bash,Shell,Grep,Tail,可以在连续流上使用grep吗 我的意思是一种tail-f命令,但是在输出上使用grep,以便只保留我感兴趣的行 我尝试过tail-f | grep模式,但似乎grep只能在tail完成后执行,也就是说永远不会执行。我一直使用tail-f | grep 它将一直等到grep刷新,而不是直到它完成(我正在使用Ubuntu)。是的,这实际上可以很好地工作Grep和大多数Unix命令一次只对一行流进行操作。从tail出来的每一行都会被分析,如果匹配,就会被传递。我认为您的问题在于grep使用了一些输出缓

可以在连续流上使用
grep

我的意思是一种
tail-f
命令,但是在输出上使用
grep
,以便只保留我感兴趣的行

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

我一直使用
tail-f | grep


它将一直等到grep刷新,而不是直到它完成(我正在使用Ubuntu)。

是的,这实际上可以很好地工作
Grep
和大多数Unix命令一次只对一行流进行操作。从tail出来的每一行都会被分析,如果匹配,就会被传递。

我认为您的问题在于grep使用了一些输出缓冲。试一试

tail -f file | stdbuf -o0 grep my_pattern

当使用BSD grep(FreeBSD、Mac OS X等)时,它会将grep的输出缓冲模式设置为无缓冲。

打开
grep
的行缓冲模式

这看起来像是不久前的事了--line buffered对于GNU grep(几乎在任何Linux上都使用)来说都无关紧要,因为它在默认情况下是刷新的(YMMV用于其他Unix,如SmartOS、AIX或QNX)。然而,截至2020年11月,需要使用线缓冲(至少在openSUSE中使用GNU grep 3.5,但根据下面的评论,它似乎是普遍需要的)。

在没有线缓冲选项的情况下,使用awk(另一个伟大的bash实用程序)而不是grep!它将不断地从tail流式传输您的数据

这就是你如何使用grep

tail -f <file> | grep pattern
tail-f | grep模式
这就是您使用awk的方式

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

在大多数情况下,您可以
tail-f/var/log/some.log | grep-foo
,它可以正常工作

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

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

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

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5
tail-F | grep-缓存行-a3-b5
-文件旋转时F更好(-F在文件旋转时不能正常工作)

-A和-B对于在模式出现前后获取线条非常有用。。这些块将出现在虚线分隔符之间

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

tail -F <file> | less
tail-F小于

如果要在流日志中搜索,这非常有用。我的意思是回顾过去,深入研究,sed将是一个更好的选择(流编辑器)

tail-n0-f | sed-n'/search string/p'

然后,如果您希望在找到特定字符串后退出tail命令:

tail--pid=$($BASHPID+1))-n0-f | sed-n'/search string/{p;q}'


显然,bashim:$BASHPID将是tail命令的进程id。sed命令位于管道中tail之后,因此sed进程id将为$BASHPID+1。

如果您希望在整个文件(而不仅仅是tail)中查找匹配项,并且希望它坐在那里等待任何新的匹配项,这将很好地工作:

tail -c +0 -f <file> | grep --line-buffered <pattern>
tail-c+0-f | grep——行缓冲

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

没有看到任何人提供我通常的方法:

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

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

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


收集邮件服务的登录信息

您肯定不会成功

tail -f /var/log/foo.log |grep --line-buffered string2search
当您使用“colortail”作为tail的别名时,例如在bash中

alias tail='colortail -n 30'
你可以顺便去看看 类型别名 如果输出类似于 tail是
colortail-n30的别名。
那么你就有了罪魁祸首:)

解决方案:

使用删除别名

unalias tail
通过此命令确保您正在使用“真实”尾部二进制文件

type tail
它应该输出如下内容:

tail is /usr/bin/tail
然后你可以运行你的命令

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

祝你好运。

生成文件的程序很可能没有刷新其输出。
tail-f file
工作(我实时看到新的输出)适用于@Luc确实,没有想到这可能是因为输入流中没有新行?如果是这样,grep将无法继续。这可能会持续相当长的一段时间,所以请不要失去耐心。大约需要多长时间?@Matthieu:主要取决于你grep的目的,以及你操作系统上的缓冲区有多大。如果grep每隔几个小时只匹配一个短字符串,那么在第一次刷新之前需要几天时间。Tail不使用输出缓冲-grep使用。不,grep在输出到tty设备时不执行输出缓冲,这一点在回答中很明显。它可以进行行缓冲!这是正确的答案,应该是公认的答案。有关更多详细信息,请参阅我对当前已接受(错误)答案的较长评论。这有一个优点,即除了
grep
之外,它还可以用于许多其他命令。但是,我在玩了很多次之后发现,一些命令仅在连接到tty时刷新其输出,为此,
取消缓冲
(在debian上的
expect dev
包中)是的,你是对的,unbuffer有时可以在stdbuf不能工作的地方工作。但我认为你正在试图找到一个“神奇”的程序,它总是能解决你的问题,而不是理解你的问题。创建一个虚拟的tty是一项无关的任务。stdbuf正是我们想要的(将标准输出缓冲区设置为给定值),而unbuffer做了很多我们可能不想要的隐藏内容(将interactive
top
与stdbuf和unbuffer进行比较)
tail is /usr/bin/tail
tail -f foo.log |grep --line-buffered something