awk和数据流通过管道无法正常工作

时间:2017-03-02 15:21:04

标签: linux bash shell awk

我今天在ubuntu 14.04下使用fifo使用awk命令和数据流时遇到了问题。

我有一个提供数据的writer.sh

#!/bin/bash

PIPE_NAME="pipe.fifo"
DATA="dataA,dataB"

# create fifo if doesn't exist
if ! [ -p "$PIPE_NAME" ]; then
    mkfifo $PIPE_NAME
fi
# keep fifo openned
sleep 10000 > $PIPE_NAME & 

while [[ true ]];
do
    echo $DATA > $PIPE_NAME
    sleep 1
done

工作正常。

在另一个shell上,如果我写命令:

cat pipe.fifo|grep data|awk -F, '{print $1}'

我没有得到任何东西

我尝试使用以下内容创建dataList.txt文件:

dataA,dataB
dataA,dataB
dataA,dataB

以下命令:

cat dataList.txt|grep data|awk -F, '{print $1}'

产生预期结果:

dataA
dataA
dataA

注意:grep命令对此没有任何兴趣,但在我的应用程序中,仅获取与特定模式匹配的数据非常有用。

你知道我误解了什么吗?

1 个答案:

答案 0 :(得分:1)

writer.sh中对管道的第一次写入将阻塞,直到从管道中读取内容。我建议像这样写writer.sh

#!/bin/bash

pipe_name="pipe.fifo"
data="dataA,dataB"

[ -p "$pipe_name" ] || mkfifo "$pipe_name"

while :; do
    echo "$data"
    sleep 1
done > "$pipe_name"

此处,管道将保持打开状态,直到您的while循环退出。

如果grep正在缓冲其输出,那么它会在数据到达时连续从管道中读取,但它不会输出任何内容到管道awk,直到缓冲区已满或直到它存在。由于writer.sh处于无限循环中,因此您只需等待缓冲区已满。

由于grep | awk的组合在某种程度上是反模式的(因为awk可以自行过滤),您可以用

替换您的阅读器
awk -F, '/data/ {print $1}' pipe.fifo

,因为它写入终端,不会缓冲其输出。