如何在Bash中添加到流中?

时间:2013-06-28 20:02:23

标签: bash stream pipe prepend

假设我在bash中有以下命令:

one | two

one运行很长时间产生输出流,two对该流的每一行执行快速操作,但two根本不起作用,除非第一行它读取的值告诉它每行读取多少个值。 one没有输出该值,但我事先知道它是什么(让我们说它是15)。我想在15\n的输出之前通过管道发送one。我不想修改onetwo

我的第一个想法是:

echo "$(echo 15; one)" | two

这给了我正确的输出,但在命令one完成之前它根本不会通过管道流。我希望输出通过管道立即开始流式传输,因为执行需要很长时间(几个月)。

我也尝试过:

echo 15; one | two

当然,输出15,但不会通过管道将其发送到two

在bash中是否有办法通过管道传递'15 \ n'然后开始通过同一个管道传输one的输出?

3 个答案:

答案 0 :(得分:13)

您只需要shell分组构造:

{ echo 15; one; } | two

大括号和尾随分号周围的空格是必需的。

测试:

one() { sleep 5; echo done; }
two() { while read line; do date "+%T - $line"; done; }
{ printf "%s\n" 1 2 3; one; } | two
16:29:53 - 1
16:29:53 - 2
16:29:53 - 3
16:29:58 - done

答案 1 :(得分:4)

使用command grouping

{ echo 15; one; } | two

完成!

答案 2 :(得分:2)

您可以使用sed执行此操作:

示例'one'脚本,每秒发出一行以显示其缓冲并运行的行。

#!/bin/bash
while [ 1 ]; do
    echo "TICK $(date)"
    sleep 1
done

然后通过此sed命令管道,请注意,对于您的特定示例'ArbitraryText'将是字段数。我使用了ArbitraryText,因此很明显这是插入的文本。在OSX上, -l <​​/ strong>与GNU Sed无缓冲我相信它是 -u

 $ ./one | sed -l '1i\
> ArbitraryText
> '

这样做是指示sed在处理文件的其余部分之前插入一行,其他所有内容都将不受影响。

最终结果是逐行处理的,没有块缓冲(或等待输入脚本完成)

ArbitraryText
TICK Fri Jun 28 13:26:56 PDT 2013
...etc

你应该能够像往常那样将它传递给'两个'。