将字符串添加到每一行的命令?

use*_*645 55 shell

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

cmd | prepend "[ERRORS] "

[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Run Code Online (Sandbox Code Playgroud)

小智 63

尝试这个:

cmd | awk '{print "[ERROR] " $0}'
Run Code Online (Sandbox Code Playgroud)

干杯

  • `awk -vT="[ERROR] " '{ print T $0 }'` 或 `awk -vT="[ERROR]" '{ print T " " $0 }'` (4认同)
  • `T="[ERROR] " awk '{ print ENVIRON["T"] $0 }'` 或 `T="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'` (2认同)
  • 我更喜欢这个解决方案,因为 bashism 会占用前导空格,例如“figlet”的输出。 (2认同)

pjz*_*pjz 56

cmd | while read line; do echo "[ERROR] $line"; done
Run Code Online (Sandbox Code Playgroud)

具有仅使用 bash 内置函数的优点,因此将创建/销毁更少的进程,因此它应该比 awk 或 sed 快一点。

@tzrik 指出它也可能是一个不错的 bash 函数。像这样定义:

function prepend() { while read line; do echo "${1}${line}"; done; }
Run Code Online (Sandbox Code Playgroud)

将允许它像这样使用:

cmd | prepend "[ERROR] "
Run Code Online (Sandbox Code Playgroud)

  • 这实际上只会将进程数减少一。(但它可能更快,因为没有使用正则表达式(`sed`)甚至字符串拆分(`awk`)。) (4认同)
  • 小心运行这样的计时测试 - 尝试以所有 6 个不同的顺序运行它们,然后平均结果。减轻块缓存影响的不同顺序和减轻后台中断/调度影响的平均顺序。 (2认同)

Eri*_*son 19

With all due credit to @grawity, I'm submitting his comment as an answer, as it seems the best answer here to me.

sed 's/^/[ERROR] /' cmd
Run Code Online (Sandbox Code Playgroud)

  • `sed X cmd` 确实读取了 `cmd` 并且不执行它。要么`cmd | sed 's/^/[ERROR] /'` 或 `sed 's/^/[ERROR] /' <(cmd)` 或 `cmd > >(sed 's/^/[ERROR] /')`。但要注意后者。即使这允许你访问 `cmd` 的返回值,`sed` 在后台运行,所以你很可能在 **after** cmd 完成后看到输出。不过,适合登录文件。请注意,`awk` 可能比 `sed` 快。 (4认同)
  • 我想这取决于你的目的。如果您的目标是简单地添加到文件中的每一行,那么使用非常熟悉的工具,只需很少的字符即可实现该目标。与 10 行 bash 脚本相比,我更喜欢它。`awk` 单行代码已经足够好了,但我认为熟悉 `sed` 的人比熟悉 `awk` 的人多。bash 脚本对它的作用很好,但它似乎在回答一个没有被问到的问题。 (2认同)

Tin*_*ino 12

我创建了一个GitHub 存储库来进行一些速度测试。

结果是:

  • 在一般情况下,awk是最快的。 sed有点慢,但perl并不比 慢多少sed。显然,所有这些都是高度优化的文本处理语言。
  • 在非常特殊的情况下,fork 占主导地位,将脚本作为编译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] $_"'
Run Code Online (Sandbox Code Playgroud)

我的一个工具的两个二进制变体(虽然它没有针对速度进行优化):

./unbuffered.dynamic -cp'[TEST] ' -q ''
./unbuffered.static -cp'[TEST] ' -q ''
Run Code Online (Sandbox Code Playgroud)

Python缓冲:

python -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'
Run Code Online (Sandbox Code Playgroud)

和 Python 无缓冲:

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


Den*_*son 5

cmd | sed 's/.*/[ERROR] &/'
Run Code Online (Sandbox Code Playgroud)

  • `sed 's/^/[错误] /'` (16认同)