awk,pipe和tail -f给出了意想不到的行为

时间:2015-10-31 05:01:28

标签: linux bash awk pipe tail

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

我在做什么时

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

我得到的结果是正确的

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 $1}; }' |
awk '{print $1}'

我没有得到任何输出。

时甚至没有输出
tail -f log | awk '{if (NF>3) {print $1}; }' | grep "64"

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:3)

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

这完全没问题:

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

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

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

您可以阅读GNU description of the issue

在任何情况下,只需检查中间使用的awk是否可以被告知以交互方式缓冲。

加了:

命令系统(“”)似乎解锁缓冲。它是POSIX,但不适用于mawk。

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

答案 2 :(得分:2)

在链接中搜索“parallel --pipe”以避免缓冲

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