我希望从文件中提取多个片段,或者至少监视日志文件中的片段(如果它们应该发生),但我不想设置多个tail | grep
会话。相反,我只想跟踪每个 grep 的输出。
我想我可以用 来做到这一点awk
,但也许已经有更接近这个想法的东西了。
例如,该命令可能如下所示:
tail -f /var/log/syslog | teegrep cron1 -f CRON | teegrep cloud-init2 -f CLOUD-INIT
输出将是文件 CRON 和 CLOUD-INIT,而所有内容最终都会发送到 stdout。只有“cron1”和“cloud-init2”行的匹配才会出现在各自的文件中。
也许它已经是命令的一部分而我只是不知道。或者可能只是一些 bash/zsh 技巧可以做同样的事情。无论哪种方式:是否有一个命令可以组合tee
和 ,grep
以便在管道中的 tee 部分可以将匹配直接匹配到文件?
答案1
假设 shell 具有进程替换,>(...)
:
tail -f /var/log/syslog |
tee >(grep cron1 >CRON) |
tee >(grep cloud-init2 >CLOUD-INIT)
这将导致为管道中的tail
第一个生成数据。tee
它将tee
复制数据并将一个副本发送到下一个副本,tee
并将另一个副本发送到进程替换中。该过程替换将grep
在来自 的数据上运行tee
,结果将写入文件CRON
。
管道的最后阶段将以类似的方式工作。
在进程替换不可用的 shell 中,例如或/bin/sh
可以使用。awk
sed
和awk
:
tail -f /var/log/syslog |
awk '{ print }
/cron1/ { print >"CRON" }
/cloud-print/ { print >"CLOUD-INIT" }'
使用sed
(请注意,我们必须确保输出文件不存在,因为命令w
总是sed
将数据附加到文件中):
rm -f CLOUD CLOUD-INIT
tail -f /var/log/syslog |
sed -e '/cloud/w CLOUD' \
-e '/cloud-print/w CLOUD-INIT'