Har*_*rma 4 linux bash awk pipe tail
这是我的示例日志文件。http://pastebin.com/DwWeFhJk。
当我在做
tail -f log | awk '{if (NF>3) {print $1}; }'
Run Code Online (Sandbox Code Playgroud)
我得到的结果是正确的
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
64.242.88.10
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时:
tail -f log |
awk '{if (NF>3) {print $1}; }' |
awk '{print $1}'
Run Code Online (Sandbox Code Playgroud)
我没有得到任何输出。甚至没有输出的情况下
tail -f log | awk '{if (NF>3) {print $1}; }' | grep "64"
Run Code Online (Sandbox Code Playgroud)
我不明白为什么第一个的输出awk
没有作为第二个awk
/grep
管道之后的输入传递。
当第一个输出awk
到达终端时,输出是行缓冲的,因此每一行都在生成时打印。当输出进入第二个awk
或 时grep
,它被完全缓冲。在缓冲区已满之前不会发送输出。当足够多的额外记录附加到日志中时,第二awk
个缓冲区将充满要处理的数据。在那之前,什么都不会发生。
小智 5
你开始命令 tail -f
,这会使输出保持打开状态,因此不会向其他命令发送所需的换行符。
这工作得很好:
cat log | awk '{if (NF>3) {print $1}; }' | grep 64
Run Code Online (Sandbox Code Playgroud)
所以,问题是缓冲。中间的 awk 正在做普通缓冲而不是交互式缓冲。这适用于(不可移植)mawk:
tail -f log | mawk -W interactive '{if (NF>3) {print $1}; }' | awk '{print}'
Run Code Online (Sandbox Code Playgroud)
您可以阅读该问题的 GNU 描述。
在任何情况下,只需检查中间使用的 awk 是否可以被告知交互式缓冲。
命令 system("") 似乎解除了缓冲的阻塞。它是 POSIX,但不适用于 mawk。
tail -f log | awk '{if (NF>3) {print $1}; system("")}' | awk '{print}'
Run Code Online (Sandbox Code Playgroud)