如何使用 sed 操作连续流输出?

如何使用 sed 操作连续流输出?

我正在为非技术观众准备一个演示文稿。我有一个在 bash 中运行的程序,它输出连续的值流,其中一些很重要。我想强调显示的重要结果,以便观众了解它们的频率。问题是我无法sed在正在运行的流上进行操作。如果我将结果放入文件中,效果很好,如下所示:

cat output.txt | sed "s/some text/some text bolded/"

但如果我在运行输出上尝试同样的操作,如下所示:

command | sed "s/some text/some text bolded/"

sed什么也没做。有什么想法吗?

正如兰伯特(Lambert)很有帮助地指出的那样,我说的“sed没有任何作用”是含糊的。发生的情况是,程序像平常一样输出到stdout(我很确定它没有写入),即使它是通过管道传输的。stderrsed

问题似乎是该命令调用第二个程序,然后该程序输出到标准输出。第一个程序打印了几行;这些我可以编辑。然后是第二个程序打印的值流;这些我无法编​​辑。

Perl 和 awk 方法也不起作用。

答案1

命令的输出很可能被缓冲。当命令写入终端时,缓冲区会在每个换行符上刷新,因此您会看到它以预期的速率出现。当命令写入管道时,缓冲区仅在达到几千字节时才刷新,因此滞后很多。这就是标准输入/输出库的默认行为。

要强制命令不影响其输出,您可以使用unbuffer(来自expect)或stdbuf(来自GNU coreutils)。

unbuffer command | sed …
stdbuf -o0 command | sed …

答案2

sed有一个选项:

-u, --无缓冲

它从输入文件加载最少量的数据并更频繁地刷新输出缓冲区。请参阅man sed了解更多详情。

答案3

我会使用 awk

  command | awk '/some important stuff/ { printf "%c[31m%s%c[0m\n",27,$0,27 ; next }
  { print ; } '

在哪里

  • /some important stuff/选择重要的行,就像在 sed 中一样
  • printf "%c[31m%s%c[0m\n",27,$0,27 ;以红色打印
    • 使用 32,33 表示绿色、黄色...
    • $1、$2,可用于选择特定字段
  • 其他行只是“按原样”打印

关键点是command应该刷新行,但如果您有大量输出,则应该是这种情况。

答案4

Perl方式:

command | perl -pe 's/(stuff)/\x1b[1m$1\x1b[0m/g'

或连续输出:

输出的 bash 脚本cont

#!/bin/bash
while [ true ]
do
   echo "Some stuff"
done

测试:

./cont | perl -pe 's/(stuff)/\x1b[1m${1}\x1b[0m/g'
  • \x1b[1m- 大胆或增加强度
  • ${1}- 反向引用
  • \x1b[0m- 重置所有属性

输出:

一些东西
一些东西
一些东西
一些东西

更多转义码这里

相关内容