Answers:
cmd | while read line; do echo "[ERROR] $line"; done
具有仅使用bash内置函数的优点,因此将更少地创建/销毁进程,因此它的触摸速度应比awk或sed更快。
@tzrik指出,它也可能会成为一个不错的bash函数。定义如下:
function prepend() { while read line; do echo "${1}${line}"; done; }
将允许它像这样使用:
cmd | prepend "[ERROR] "
sed
表达式(awk
)甚至不使用字符串拆分()。)
function prepend() { while read line; do echo "${1}${line}"; done; }
尝试这个:
cmd | awk '{print "[ERROR] " $0}'
干杯
awk -vT="[ERROR] " '{ print T $0 }'
或awk -vT="[ERROR]" '{ print T " " $0 }'
T="[ERROR] " awk '{ print ENVIRON["T"] $0 }'
或T="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'
cmd | awk '{print "['$V]' " $0}'
-应该在开始时对其进行一次评估,因此不会增加性能开销。
感谢@grawity,我正在提交他的评论作为答案,因为这似乎是我的最佳答案。
sed 's/^/[ERROR] /' cmd
awk
一个班轮是足够好的,但我认为,越来越多的人所熟悉的sed
比awk
。bash脚本可以很好地完成它的工作,但似乎正在回答一个未被询问的问题。
sed X cmd
会读取cmd
并且不会执行它。无论是cmd | sed 's/^/[ERROR] /'
或sed 's/^/[ERROR] /' <(cmd)
或cmd > >(sed 's/^/[ERROR] /')
。但是要当心后者。即使这允许您访问的返回值cmd
将sed
在后台运行,所以它可能是你可以看到输出后完成CMD。不过,它非常适合登录文件。请注意,这awk
可能比sed
。
alias lpad="sed 's/^/ /'"
。我插入4个前导空格而不是错误。现在,对于魔术来说: ls | lpad | pbcopy
将ls输出前加4个空格,将其标记为Markdown进行代码,这意味着您将剪贴板(在Mac上为pbcopy抓取剪贴板)直接粘贴到StackOverflow或任何其他markdown上下文中。不能alias
在AWK答案(1日试)所以这1个胜场。在 同时读解也是别名能干,但我觉得这sed的更具表现力。
我创建了一个GitHub存储库以进行一些速度测试。
结果是:
awk
最快。 比sed
慢perl
一点也不慢多少sed
。显然,所有这些都是用于文本处理的高度优化的语言。ksh
脚本(shcomp
)运行可以节省更多的处理时间。相比之下,bash
与编译ksh
脚本相比,速度非常慢。awk
似乎是不值得的。相比之下python
,速度非常慢,但是我没有测试过编译过的情况,因为在这种脚本情况下通常不会这样做。
测试了以下变体:
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] $_"'
我的一种工具的两个二进制变体(不过,它并没有被速度优化):
./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,'
awk -v T="[TEST %Y%m%d-%H%M%S] " '{ print strftime(T) $0 }'
输出时间戳
我想要一个可以处理stdout和stderr的解决方案,因此我编写prepend.sh
并放入了它的路径:
#!/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分开。
>(
子shell发生了一些我无法完全解决的问题。似乎脚本已完成,并且提示返回后,输出已到达终端,这有点混乱。我最终在这里想出了答案stackoverflow.com/a/25948606/409638