我正在尝试执行
tail -100000f MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3" | cut -c 3,4,5,6 | awk '{if($1>20)print$1}'
我什么也没得到。
但与
tail -100000 MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3" | cut -c 3,4,5,6 | awk '{if($1>20)print$1}'
我得到了预期的结果:
212
45
29
463
544
556
543
1115
830
802
119
95
33
31
194
170
127
97
我需要它-f
,以便我可以读取文件中出现的大于 20 的新数字。
减少行数也是一种选择,我可以从少量开始,例如-100。
该tail -f
作品适用于:
tail -100000f MXMLExchangeMonitoring_Mx3.log | egrep "INTENTO.*Workflow" | cut -d ":" -f "3"
答案1
命令与标准输出不是终端(这里是管道之前的命令)将具有 stdio C 函数(例如fwrite()
)进行块(又名完整)缓冲。这是行为的一些描述setvbuf(3)
(这是标准 C 和POSIX函数,但描述取自 GNU 变体。POSIX可能表明确切的行为是实现定义的):
通常情况下所有文件都是块缓冲的。如果一个流引用了一个 终端(如标准输出通常是这样),它是行缓冲的。标准错误流标准错误默认情况下始终不缓冲。
除最后一个管道之外的一系列管道中的所有命令都可能受到影响:它们获得块缓冲其输出的正常行为。
这是至少在 Linux 和 FreeBSD 上有效的方法。
某些命令 (
tail
) 的行为与此“预期”相同没事做。
其他 (
grep
) 对此有选项对于 GNU 和 *BSD(甚至 Mac OS X),
grep
有一个内置--line-buffered
选项可以更改其行为其他 (
cut
) 则不然。有解决方法,可能是系统特定的在 GNU 以及 FreeBSD 系统(但显然不是其他 *BSD 变体)上有一个 libc 包装工具
stdbuf
目的是:tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq
这将立即显示 access.log 中的唯一条目
awk
位于管道的末尾并输出到终端,因此不受影响(即:它已经是行缓冲的)如果稍后需要,此工具包含
fflush()
用于达到相同效果的命令。
所有这些动态链接的工具都应该支持使用,stdbuf -o L
即使不使用它们的某些专用功能,但最好不要使用 libc 包装器(如果可能的话)。
考虑到所有这些,并且stdbuf
安装后,此修改后的行应该按预期运行(我将其分成多行以使其更易于阅读):
tail -100000f MXMLExchangeMonitoring_Mx3.log |
egrep --line-buffered "INTENTO.*Workflow" |
stdbuf -o L cut -d ":" -f "3" |
stdbuf -o L cut -c 3,4,5,6 |
awk '{if($1>20)print$1}'
在一些更简单的过滤情况下,只需重新排序命令以仅保留其行为不易更改的命令(如最后一个那样)就足够了。但如果没有stdbuf
,即使有两个cut
正在酝酿中也无法解决问题。