如何在Bash中为流做准备



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

one | two

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

我的第一个想法是:

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

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

我也试过:

echo 15; one | two

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

bash中是否有方法通过管道传递"15\n",然后开始通过同一管道流式传输one的输出?

您只需要shell分组构造:

{ echo 15; one; } | two

大括号周围的空格和后面的分号是必需的。

测试:

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

使用命令分组:

{ echo 15; one; } | two

完成!

您可以使用sed:

示例"one"脚本,每秒发出一行,以显示它的行缓冲和正在运行。

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

然后通过这个sed命令进行管道传输,注意对于您的特定示例,"ArbitraryText"将是字段数。我使用了ArbitraryText,所以很明显这就是插入的文本。在OSX上,-l没有GNU Sed缓冲,我相信它是-u

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

这样做的目的是指示sed在处理文件的其余部分之前插入一行,其他所有内容都将原封不动地通过。

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

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

然后,你应该能够像往常一样将其转换为"两个"。

相关内容

  • 没有找到相关文章

最新更新