unix实用程序尾部读取整个文件吗?

时间:2015-07-04 12:34:39

标签: design-patterns filter grep cgi tail

我使用tail实用程序和-f选项来查看我的一个日志文件。我的CGI程序总是只将日志文件的最后40行发送到我的网页,在那里我可以实时监控日志和声音通知。现在我只想发送满足某些条件的最后40行,例如。匹配任何模式。我想我必须使用grep,但是如何才能选择最后40个匹配的行呢?我是否必须使用" tail"两次?

2 个答案:

答案 0 :(得分:0)

grep condition file | tail -40

如果那不是您想要的,那么编辑您的问题以显示一些示例输入和预期输出(不过40行以上)。

https://stackoverflow.com/a/31220727/1745001下的评论中进行性能讨论:在一个1M行文件中,“bar”出现1,000次,而每隔一行只是“foo”,由此脚本创建:

 awk 'BEGIN{for (i=1;i<=1000000;i++) print (i%1000 ? "foo" : "bar")}' > file

这是cygwin下bash 4.3.33中的第三次运行时间:

$ time (grep bar file | tail -40) >/dev/null
real    0m0.050s
user    0m0.030s
sys     0m0.045s

$ time (tac file | grep bar | head -40 | tac) >/dev/null
real    0m0.100s
user    0m0.061s
sys     0m0.107s

$ time (tac file | grep -m 40 bar | tac) >/dev/null
real    0m0.080s
user    0m0.000s
sys     0m0.090s

在由:

创建的100M文件上
awk 'BEGIN{for (i=1;i<=100000000;i++) print (i%1000 ? "foo" : "bar")}' > file

我明白了:

$ time (grep bar file | tail -40) >/dev/null
real    0m1.014s
user    0m0.841s
sys     0m0.202s

$ time (tac file | grep bar | head -40 | tac) >/dev/null
real    0m1.154s
user    0m1.262s
sys     0m0.248s

$ time (tac file | grep -m 40 bar | tac) >/dev/null
real    0m0.078s
user    0m0.015s
sys     0m0.046s

完全符合预期。对于前2个,grep在搜索整个文件时执行完全相同的处理,这是驱动大部分持续时间的因素,工作负载的唯一差异是tail vs tac+pipe+head+pipe+tac,而第3个一个grep在第40场比赛后退出的工作少得多,因此总体管道更快。

答案 1 :(得分:-1)

tac file | grep "your regexp here" | head -40 | tac

time (grep bar file | tail -40) >/dev/null
real    0m15.472s
user    0m15.316s
sys     0m0.172s

time (tac file | grep bar | head -40 | tac) >/dev/null
real    0m0.146s
user    0m0.184s
sys     0m0.004s

time (tac file | grep -m40 bar | tac) >/dev/null
real    0m0.005s
user    0m0.000s
sys     0m0.000s

发现别名grep="grep -P",以便获得干净的grep结果:

time ("grep" bar file | tail -40) >/dev/null

real    0m1.316s
user    0m1.164s
sys     0m0.172s

time (tac file | "grep" bar | head -40 | tac) >/dev/null
real    0m0.071s
user    0m0.040s
sys     0m0.092s

time (tac file | "grep" -m40 bar | tac) >/dev/null
real    0m0.042s
user    0m0.004s
sys     0m0.056s