awk、pipe 和 tail -f 给出意外行为

Awk, pipe and tail -f giving unexpected behavior

这是我的示例日志文件。http://pastebin.com/DwWeFhJk

当我在做的时候

tail -f log | awk '{if (NF>3) {print }; }'

我得到的结果是正确的

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

但是当我在做的时候:

tail -f log |
awk '{if (NF>3) {print }; }' |
awk '{print }'

我没有得到任何输出。在

的情况下甚至没有输出
tail -f log | awk '{if (NF>3) {print }; }' | grep "64"

我不明白第一个 awk 的输出没有作为管道后第二个 awk/grep 的输入传递的原因。

当第一个 awk 的输出进入终端时,输出是行缓冲的,因此每行在生成时打印。当输出转到第二个 awkgrep 时,它是完全缓冲的。在缓冲区已满之前不会发送输出。当足够多的额外记录附加到日志时,第二个 awk 将一个充满数据的缓冲区进行处理。在那之前,什么都不会发生。

您使用 tail -f 启动命令,这会保持输出打开,因此不会向其他命令发送所需的换行符。

这很好用:

cat log | awk '{if (NF>3) {print }; }' | grep 64

所以,问题是缓冲。中间的 awk 正在做正常的缓冲而不是交互式缓冲。这与 mawk 一起工作(不可移植):

tail -f log | mawk -W interactive '{if (NF>3) {print }; }' | awk '{print}'

你可以阅读 GNU description of the issue

无论如何,只需检查中间使用的awk是否可以交互缓冲。

已添加:

命令 system("") 似乎解除了缓冲。它是 POSIX,但不适用于 mawk。

tail -f log | awk '{if (NF>3) {print }; system("")}' | awk '{print}'

在 link 中搜索 "parallel --pipe" 以避免缓冲

https://www.gnu.org/software/parallel/parallel_tutorial.html