Looking for something like this? Any ideas?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Looking for something like this? Any ideas?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Try this:
cmd | awk '{print "[ERROR] " $0}'
Cheers
cmd | while read line; do echo "[ERROR] $line"; done
has the advantage of only using bash builtins so fewer processes will be created/destroyed so it should be a touch faster than awk or sed.
@tzrik points out that it might also make a nice bash function. Defining it like:
function prepend() { while read line; do echo "${1}${line}"; done; }
would allow it to be used like:
cmd | prepend "[ERROR] "
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
I created a GitHub repository to do some speed tests.
The result is:
awk
is fastest. sed
is a bit slower and perl
is not much slower than sed
. Apparently, all those are highly optimized languages for text processing.ksh
script (shcomp
) can save even more processing time. In contrast, bash
is dead slow compared to compiled ksh
scripts.awk
seems not be worth the effort.In contrast python
is dead slow, but I have not tested a compiled case, because it is usually not what you would do in such a scripting case.
Following variants are tested:
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] $_"'
Two binary variants of one of my tools (it is not optimzed for speed, though):
./unbuffered.dynamic -cp'[TEST] ' -q ''
./unbuffered.static -cp'[TEST] ' -q ''
Python buffered:
python -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'
And Python unbuffered:
python -uSc 'import sys
while 1:
line = sys.stdin.readline()
if not line: break
print "[TEST]",line,'
I wanted a solution that handled stdout and stderr, so I wrote prepend.sh
and put it in my 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)
Now I can just run prepend.sh "[ERROR]" cmd ...
, to prepend "[ERROR]" to the output of cmd
, and still have stderr and stdout separate.
cmd | xargs -L 1 -i echo "prefix{}"
or even easier in case prefix
is space-delimited from the line itself
cmd | xargs -L 1 echo prefix
This is not very efficient performance-wise, but short to write.
It works by running echo
once per each line of input. xargs
allows you to also process \0
-delimited lines.
Moreutils has the ts
command, which can be abused to do what you need:
cmd | ts "[ERRORS]"
It's probably slower than the other solutions, but much shorter...