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


13

我正在为非技术性观众准备一个演讲。我有一个在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

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

Perl和awk方法也不起作用。


5
stdbuf -o0 command | sed "s/some text/some text bolded/"工作吗?
FloHimself 2015年

3
使用“ sed什么都不是”,您的意思是未进行替换,或者您没有任何输出?该命令可能正在写入stderr而不是stdout?如果您想突出显示某些内容,可以使用command|egrep 'some text|$'
Lambert

命令是否写到stdout(而不是stderr)?
Anthon 2015年

1
鉴于文本不止一次出现,您应该添加一个g“全局”替换,否则仅替换一行中的第一个匹配项:sed "s/old/new/g"
ph0t0nix

@ ph0t0nix不,这不是问题,但是这可能是一个问题。谢谢你的提示。
P琼斯

Answers:


12

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

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

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

stdbuf没用(前面提到过,顺便说一句),但是unbuffer没用!!你不知道你让我多么幸福。
P琼斯

并感谢您的简要说明。非常有帮助。
P琼斯

sed本身使用这样的缓冲,(CF ChennyStar后),所以这里的例子可能无法正常工作,因为sedcommand到非缓冲:cat /etc/passwd | unbuffer sedsed本身有一个-u选项,因此grep可能会在这方面的例子更suiteable。非常感谢您提供背景信息!好答案!
数学

4

sed 有一个选择:

-u,-无缓冲

它从输入文件中加载最少的数据,并更频繁地刷新输出缓冲区。请参阅man sed以获取更多详细信息。


1
sed仅GNU (不是BSD sed),我相信这仍然不会阻止在管道开始时缓冲命令。但值得一提。:)
通配符

stdbuf联机帮助页指出:“如果COMMAND调整其标准流的缓冲(例如'tee',那么)将覆盖'stdbuf'的相应更改。” 看起来sed可能属于此类,但是'-u'标志将使其在未缓冲的管道链中很有用。
MattSmith

2

我会用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应该刷新行,但是如果您有很多输出,情况应该是这样。


注意:问题不是说整个行应“固定”,而应是“某些文本”。尽管有可能在awk(使用sub()gsub())中实现该功能,但在这种原始替换的情况下,sed无疑是合适的工具。
Janis

1

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 -重置所有属性

输出:

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

这里有更多转义码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.