是否可以在连续流上使用grep?
grep
我的意思是有点像tail -f <file>命令,但是输出上有grep,以便只保留我感兴趣的行。
tail -f <file>
我尝试过tail -f <file> | grep pattern,但似乎grep只能在tail完成后执行,也就是说永远不会。
tail -f <file> | grep pattern
tail
我一直使用tail -f <file> | grep <pattern>。
tail -f <file> | grep <pattern>
它将等待grep刷新,而不是直到它完成(我使用的是Ubuntu)。
是的,这实际上可以很好地工作。Grep和大多数Unix命令一次对流进行一行操作。如果匹配,则会分析并传递从尾部出来的每一行。
Grep
我认为你的问题是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
看起来不久前--line-buffered对GNU grep来说并不重要(几乎在任何Linux上使用),因为它默认刷新(YMMV用于其他Unix类如SmartOS、AIX或QNX)。然而,截至2020年11月,需要--line-buffered(至少在openSUSE中使用GNU grep 3.5,但根据下面的评论,似乎通常需要它)。
--line-buffered
在你没有行缓冲选项的地方使用awk(另一个很棒的bash实用程序)而不是grep!它会不断地从尾巴流式传输你的数据。
这就是你如何使用grep
这就是你如何使用awk
tail -f <file> | awk '/pattern/{print $0}'
在大多数情况下,你可以tail -f /var/log/some.log |grep foo,它会很好地工作。
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
-F在文件旋转的情况下更好(如果文件旋转,-f将无法正常工作)
-A和-B用于在模式出现之前和之后获取线条…这些块将出现在虚线分隔符之间
但对我来说,我更喜欢做以下事情
tail -F <file> | less
如果你想在流式日志中搜索,这是非常有用的。我的意思是回顾和前进,深入观察
ed是更好的选择(流编辑器)
tail -n0 -f <file> | sed -n '/search string/p'
然后,如果您希望在找到特定字符串后退出尾巴命令:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
显然是一种粗俗主义:$BASHPID将是尾巴命令的进程ID。se命令紧随管道中的尾巴之后,因此se进程ID将是$BASHPID+1。
如果你想在整个文件中找到匹配项(不仅仅是尾部),并且你希望它坐下来等待任何新的匹配项,这很有效:
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
这个命令对我有用(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
当你使用“彩色尾巴”作为尾巴的别名时,例如。在bash中
alias tail='colortail -n 30'
您可以查看类型别名如果这个输出类似尾巴是colortail -n 30的别名。然后你有你的罪魁祸首:)
colortail -n 30
解决方案:
删除别名
unalias tail
确保您使用此命令的“真正”尾二进制文件
type tail
它应该输出如下内容:
tail is /usr/bin/tail
然后你就可以运行你的命令了
tail -f foo.log |grep --line-buffered something
祝你好运。
在这个问题上有点晚了,考虑到这种工作是监控工作的重要组成部分,这是我的(没那么短)答案…
这个命令比在已经发布的答案上读到的要少一些
遵循选项tail -f和tail -F之间的区别,从manpage:
tail -f
tail -F
-f, --follow[={name|descriptor}]output appended data as the file grows;...-F same as --follow=name --retry...--retrykeep trying to open a file if it is inaccessible
这意味着:通过使用-F而不是-f,tail将在删除时重新打开文件(对于示例,在日志轮换时)。这对于在许多天内查看日志文件很有用。
-F
-f
同时跟随不止一个文件的能力我已经用过了:
tail -F /var/www/clients/client*/web*/log/{error,access}.log /var/log/{mail,auth}.log \/var/log/apache2/{,ssl_,other_vhosts_}access.log \/var/log/pure-ftpd/transfer.log
通过数百个文件跟踪事件…(请考虑此答案的其余部分,以了解如何使其具有可读性…;)
使用开关-n(不要使用-c进行行缓冲!)。默认情况下tail将显示最后10行。这可以调整:
-n
tail -n 0 -F file
将跟随文件,但只会打印新行
tail -n +0 -F file
将在跟随他的进展之前打印整个文件。
如果您计划过滤ouptuts,请考虑缓冲!请参阅sed的-u选项,grep的--line-buffered或stdbuf命令:
sed
-u
stdbuf
tail -F /some/files | sed -une '/Regular Expression/p'
是(比使用grep更有效)比如果你不使用sed命令中的-u开关更具反应性。
tail -F /some/files |sed -une '/Regular Expression/p' |stdbuf -i0 -o0 tee /some/resultfile
在最近的系统上,而不是tail -f /var/log/syslog,你必须以几乎相同的方式运行journalctl -xf…
tail -f /var/log/syslog
journalctl -xf
journalctl -axf | sed -une '/Regular Expression/p'
但是阅读man page,这个工具是为日志分析而构建的!
man page
两个(或更多)文件的彩色输出
这是一个脚本观察许多文件的示例,第一个文件的着色方式与其他文件不同:
#!/bin/bash tail -F "$@" |sed -une "/^==> /{h;};//!{G;s/^\\(.*\\)\\n==>.*${1//\//\\\/}.*<==/\\o33[47m\\1\\o33[0m/;s/^\\(.*\\)\\n==> .* <==/\\o33[47;31m\\1\\o33[0m/;p;}"
它们在我的主机上运行良好,运行:
sudo ./myColoredTail /var/log/{kern.,sys}log
交互式脚本
您可能正在查看日志以对事件做出反应?
这是一个小脚本,当一些USB设备出现或消失时播放一些声音,但相同的脚本可以发送邮件或任何其他交互,例如打开咖啡机…
#!/bin/bash exec {tailF}< <(tail -F /var/log/kern.log)tailPid=$! while :;doread -rsn 1 -t .3 keyboard[ "${keyboard,}" = "q" ] && breakif read -ru $tailF -t 0 _ ;thenread -ru $tailF linecase $line in*New\ USB\ device\ found* ) play /some/sound.ogg ;;*USB\ disconnect* ) play /some/othersound.ogg ;;esacprintf "\r%s\e[K" "$line"fidone echoexec {tailF}<&-kill $tailPid
您可以按Q键退出。