命令预加string到每一行?

寻找这样的东西? 有任何想法吗?

cmd | prepend "[ERRORS] " [ERROR] line1 text [ERROR] line2 text [ERROR] line3 text ... etc 

 cmd | while read line; do echo "[ERROR] $line"; done 

具有只使用bash内build的好处,所以更less的进程将被创build/销毁,所以它应该比awk或sed更快。

尝试这个:

 cmd | awk '{print "[ERROR] " $0}' 

干杯

随着@grawity的所有应有的功劳,我正在提交他的评论作为答案,因为这似乎是对我来说最好的答案。

 sed 's/^/[ERROR] /' cmd 
 cmd | sed 's/.*/[ERROR] &/' 

我创build了一个GitHub仓库来做一些速度testing。

结果是:

  • 在一般情况下, awk是最快的。 sed有点慢, perl也不比sed慢很多。 显然,所有这些都是高度优化的文本处理语言。
  • 在非常特殊的情况下,叉子占主导地位,将脚本作为编译的ksh脚本( shcomp )运行可以节省更多的处理时间。 相比之下,与编译的ksh脚本相比, bash的速度非常慢。
  • 创build一个静态链接的二进制文件来打败awk似乎不值得。

相比之下, python是死的缓慢,但我没有testing一个编译的案例,因为它通常不是你会在这样的脚本的情况下做什么。

testing以下变体:

 while read line; do echo "[TEST] $line"; done while read -r line; do echo "[TEST] $line"; done while read -r line; do echo "[TEST]" $line; done while read -r line; do echo "[TEST]" "$line"; done sed 's/^/[TEST] /' awk '{ print "[TEST] " $0 }' awk -vT="[TEST] " '{ print T $0 }' awk -vT="[TEST]" '{ print T " " $0 }' awk -vT="[TEST]" 'BEGIN { T=T " "; } { print T $0 }' T="[TEST] " awk '{ print ENVIRON["T"] $0 }' T="[TEST]" awk '{ print ENVIRON["T"] " " $0 }' T="[TEST]" awk 'BEGIN { T=ENVIRON["T"] " " } { print T $0 }' perl -ne 'print "[TEST] $_"' 

我的一个工具的两个二进制变体(尽pipe速度不是最优的):

 ./unbuffered.dynamic -cp'[TEST] ' -q '' ./unbuffered.static -cp'[TEST] ' -q '' 

Python缓冲:

 python -uSc 'import sys for line in sys.stdin: print "[TEST]",line,' 

和Python无缓冲:

 python -uSc 'import sys while 1: line = sys.stdin.readline() if not line: break print "[TEST]",line,' 

我想要一个处理stdout和stderr的解决scheme,所以我写了prepend.sh并把它放在我的path中:

 #!/bin/bash prepend_lines(){ local prepended=$1 while read line; do echo "$prepended" "$line" done } tag=$1 shift "$@" > >(prepend_lines "$tag") 2> >(prepend_lines "$tag" 1>&2) 

现在我可以运行prepend.sh "[ERROR]" cmd ... ,将“[ERROR]”添加到cmd的输出中,并且仍然将stderr和stdout分开。