unix 实用程序 tail 是否读取整个文件?
Does unix utility tail read through the whole file?
我使用带有选项 -f 的 tail 实用程序来查看我的一个日志文件。我的 CGI 程序总是只将日志文件的最后 40 行发送到我的网页,在那里我可以实时监控日志并发出声音通知。现在我只想发送满足某些条件的最后 40 行,例如。匹配任何模式。我想我必须使用 grep,但我如何才能 select 只有最后 40 个匹配行?我必须使用 "tail" 两次吗?
grep condition file | tail -40
如果这不是您想要的,那么编辑您的问题以显示一些示例输入和预期输出(尽管不值得 40 多行)。
wrt 下评论中的性能讨论:在一个 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 场比赛后退出,所以整个管道更快。
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
我使用带有选项 -f 的 tail 实用程序来查看我的一个日志文件。我的 CGI 程序总是只将日志文件的最后 40 行发送到我的网页,在那里我可以实时监控日志并发出声音通知。现在我只想发送满足某些条件的最后 40 行,例如。匹配任何模式。我想我必须使用 grep,但我如何才能 select 只有最后 40 个匹配行?我必须使用 "tail" 两次吗?
grep condition file | tail -40
如果这不是您想要的,那么编辑您的问题以显示一些示例输入和预期输出(尽管不值得 40 多行)。
wrt
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 场比赛后退出,所以整个管道更快。
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