将尾部输出重定向到文件,然后在找到匹配时停止

将尾部输出重定向到文件,然后在找到匹配时停止

有这个日志文件,数据进来是连续的。我想要发生的是 tail -f 这个日志文件,然后将其重定向到具有 ff 条件的文件

日志文件内容示例

aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc
ddddddddddddddd
eeeeeeeeeeeeeee
fffffffffffffff
ggggggggggggggg
hhhhhhhhhhhhhhh
iiiiiiiiiiiiiii

在拖尾中,我希望重定向在找到第一个模式时开始,然后在找到第二个模式时停止重定向和拖尾。例如

我希望重定向在发现模式“dddddddddddddd”时启动,然后在发现“hhhhhhhhhhhhhh”时停止,从重定向创建的文件的内容应该是

ddddddddddddddd
eeeeeeeeeeeeeee
fffffffffffffff
ggggggggggggggg
hhhhhhhhhhhhhhh

在编码中我正在考虑这样的事情。但我不知道当发现第二个模式时如何停止重定向。

tail -f logfile > log.tmp
while grep "ddddddddddddddd" log.tmp
do
cat log.tmp > logfile
done

答案1

这正是retail做。retail是带有正则表达式的 tail,这是我为您此处的用例编写的工具。在你的情况下,你会使用:

retail -f -r ddddddddddddddd -u hhhhhhhhhhhhhhh logfile > log.tmp

-f是标准tail -f选项。-r接受一个正则表达式来开始要包含的行范围,并-u接受一个正则表达式让它继续下去。它开始于最后的出现图案-r并在打印后退出第一的-u此后该模式的出现。

如果您想从模式的第一个实例开始,可以-b与 结合使用-r。两个正则表达式都是ERE,没有任何隐式锚定,但您可以像往常一样使用^$来锚定匹配。


您可以retail通过以下方式获取和构建:

git clone https://github.com/mwh/retail.git
cd retail
./configure
make
make install

~/.local/bin它默认安装,但您可以更改它,或者只是将可执行文件复制到您想要的位置。


retail是完全POSIX 兼容,尽管我不建议实际使用它作为您的系统tail

答案2

如果我理解您的要求正确,这将符合您的期望:

awk '/ddddddddddddddd/,/hhhhhhhhhhhhhhh/ { print > "excerpt" } 1' infile | tail -f

awk作为文件“infile”的过滤器;它将给定模式之间的所有内容打印到文件“摘录”中,并且还将每一行打印到标准输出,然后像tail -f往常一样进行处理。

如果您想将其与流数据一起使用:

some_process | awk '/ddddddddddddddd/,/hhhhhhhhhhhhhhh/ { print > "excerpt" } 1'  | tail -f

(注意:由于tail -f是一个交互式程序,如果可能的话,它应该始终出现在管道中。)

答案3

也许您可以awk在这里使用 的范围模式:

tail -f logfile | awk '/ddddddddddddddd/,/hhhhhhhhhhhhhhh/'

如果您需要规避该SIGPIPE问题,您可以使用以下socat方法来代替tail该工作:

socat -u file:logfile,ignoreeof "system:'stdbuf -o0 awk /ddddddddddddddd/,/hhhhhhhhhhhhhhh/'" > logfile.new

相关内容