如何“grep”连续流?
- 2024-09-30 14:02:00
- admin 原创
- 139
问题描述:
grep
可以在连续流中使用吗?
我的意思是一种tail -f <file>
命令,但是grep
在输出中只保留我感兴趣的行。
我试过了tail -f <file> | grep pattern
但是似乎grep
只能执行一次tail
完成,也就是说永远不会。
解决方案 1:
使用 BSD grep (FreeBSD、Mac OS X 等) 时打开grep
的行缓冲模式
tail -f file | grep --line-buffered my_pattern
不久前,--line-buffered
GNU grep(几乎可用于任何 Linux)似乎没有问题,因为它默认会刷新(对于其他类 Unix,例如 SmartOS、AIX 或 QNX,情况可能有所不同)。但是,截至 2020 年 11 月,--line-buffered
需要(至少在 openSUSE 中 GNU grep 3.5 需要,但根据下面的评论,似乎通常需要)。
解决方案 2:
我tail -f <file> | grep <pattern>
一直都在使用它。
它将等到 grep 刷新,而不是等到它完成(我正在使用 Ubuntu)。
解决方案 3:
我认为你的问题是 grep 使用了一些输出缓冲。尝试
tail -f file | stdbuf -o0 grep my_pattern
它将把 grep 的输出缓冲模式设置为无缓冲。
解决方案 4:
如果你想在整个文件(而不仅仅是尾部)中查找匹配项,并且希望它等待任何新的匹配项,那么这样做很好:
tail -c +0 -f <file> | grep --line-buffered <pattern>
该-c +0
标志表示输出应从文件开头0
()开始字节()。-c
`+`
解决方案 5:
在大多数情况下,您可以tail -f /var/log/some.log |grep foo
并且它会正常工作。
如果您需要在正在运行的日志文件上使用多个 grep,但发现没有输出,则可能需要将开关--line-buffered
插入中间的grep,如下所示:
tail -f /var/log/some.log | grep --line-buffered foo | grep bar
解决方案 6:
您可能会认为这个答案是一种增强。通常我使用
tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5
如果文件旋转,-F 效果会更好(如果文件旋转,-f 将无法正常工作)
-A 和 -B 有助于获取模式出现之前和之后的线条。这些块将出现在虚线分隔符之间
但对我来说,我更喜欢做以下事情
tail -F <file> | less
如果你想在流日志中搜索,这非常有用。我的意思是来回查看并深入查看
解决方案 7:
没有看到任何人提供我通常的做法:
less +F <file>
ctrl + c
/<search term>
<enter>
shift + f
我更喜欢这个,因为您可以ctrl + c
随时使用它来停止和浏览文件,然后只需点击shift + f
即可返回实时流式搜索。
解决方案 8:
sed会是一个更好的选择(流编辑器)
tail -n0 -f <file> | sed -n '/search string/p'
然后,如果您希望 tail 命令在找到特定字符串后退出:
tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'
显然是 bashism:$BASHPID 将是 tail 命令的进程 ID。sed 命令在管道中位于 tail 之后,因此 sed 进程 ID 将是 $BASHPID+1。
解决方案 9:
这个问题问得有些晚了,考虑到这类工作是监控工作的重要组成部分,这是我的(不太简短的)回答...
使用以下日志狂欢
命令
tail
这个命令比已经发布的答案更详细一些
follow选项
tail -f
和man 页tail -F
中的 ,之间的区别:
-f, --follow[={name|descriptor}] output appended data as the file grows; ... -F same as --follow=name --retry ... --retry keep trying to open a file if it is inaccessible
这意味着:通过使用-F
而不是-f
,tail
将在删除时重新打开文件(例如,在日志轮换时)。
这对于查看多天的日志文件很有用。
我已经使用过同时关注多个文件的能力:
tail -F /var/www/clients/client*/web*/log/{error,access}.log /var/log/{mail,auth}.log \n /var/log/apache2/{,ssl_,other_vhosts_}access.log \n /var/log/pure-ftpd/transfer.log
通过数百个文件跟踪事件...(考虑这个答案的其余部分以了解如何使其可读......;)
使用开关
-n
(不要-c
用于行缓冲!)。
默认情况下tail
将显示最后 10 行。这可以调整:
tail -n 0 -F file
将跟踪文件,但只会打印新行
tail -n +0 -F file
在跟踪他的进展之前将打印整个文件。
2.管道传输时的缓冲问题:
如果您计划过滤输出,请考虑缓冲!请参阅-u
选项sed
、--line-buffered
或命令grep
:stdbuf
tail -F /some/files | sed -une '/Regular Expression/p'
比使用更有效率,比在命令中不使用 switchgrep
更灵敏。-u
`sed`
tail -F /some/files |
sed -une '/Regular Expression/p' |
stdbuf -i0 -o0 tee /some/resultfile
最近日志系统
在最近的系统上,tail -f /var/log/syslog
您不必journalctl -xf
以几乎相同的方式运行......
journalctl -axf | sed -une '/Regular Expression/p'
但请阅读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 :;do
read -rsn 1 -t .3 keyboard
[ "${keyboard,}" = "q" ] && break
if read -ru $tailF -t 0 _ ;then
read -ru $tailF line
case $line in
*New USB device found* ) play /some/sound.ogg ;;
*USB disconnect* ) play /some/othersound.ogg ;;
esac
printf "
%se[K" "$line"
fi
done
echo
exec {tailF}<&-
kill $tailPid
您可以按键退出Q
。
解决方案 10:
是的,这确实可以正常工作。Grep
大多数 Unix 命令每次对流进行一行操作。tail 输出的每一行都会被分析,如果匹配,则传递。
解决方案 11:
这个命令对我有用(Suse):
mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN >> logins_to_mail
收集邮件服务的登录信息
解决方案 12:
你肯定不会成功
tail -f /var/log/foo.log |grep --line-buffered string2search
当您使用“colortail”作为 tail 的别名时,例如在 bash 中
alias tail='colortail -n 30'
您可以通过类型别名进行检查,如果输出类似 tail isan alias of 的内容colortail -n 30
,则说明您找到了罪魁祸首:)
解决方案:
删除别名
unalias tail
确保你正在通过此命令使用“真正的” tail 二进制文件
type tail
输出内容如下:
tail is /usr/bin/tail
然后你可以运行你的命令
tail -f foo.log |grep --line-buffered something
祝你好运。
解决方案 13:
在没有行缓冲选项的情况下,使用 awk(另一个很棒的 bash 实用程序)代替 grep!它将连续从 tail 流式传输数据。
这就是你使用 grep 的方式
tail -f <file> | grep pattern
这是你使用 awk 的方式
tail -f <file> | awk '/pattern/{print $0}'
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件