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
awk -vT="[ERROR] " '{ print T $0 }' or awk -vT="[ERROR]" '{ print T " " $0 }'
– Tino
Feb 21 '14 at 23:30
T="[ERROR] " awk '{ print ENVIRON["T"] $0 }' or T="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'
– Tino
Feb 21 '14 at 23:31
cmd | awk '{print "['$V]' " $0}' - this should be evaluated once at the start, so no performance overhead.
– robert
Aug 07 '18 at 09:10
figlet.
– Richard Barber
Jul 30 '21 at 06:24
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] "
sed) or even string splitting (awk) are used.)
– u1686_grawity
Oct 09 '09 at 07:52
function prepend() { while read line; do echo "${1}${line}"; done; }
– tzrlk
Feb 01 '18 at 20:48
set -o pipefail in your script.
– rudolfbyker
Apr 20 '20 at 09:00
cmd | while read line; do echo "[ERROR] $line"; done so that it opens the file I want?
– Nazar
Sep 29 '20 at 23:53
cat ./your-file | while read line; do echo "[ERROR] $line"; done
– Seweryn Niemiec
Jan 15 '21 at 15:18
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
awk one-liner is nice enough, but I think that more people are familiar with sed than awk. The bash script is good for what it does, but it seems that it is answering a question that was not asked.
– Eric Wilson
Jan 31 '12 at 18:22
sed X cmd does read cmd and does not execute it. Either cmd | sed 's/^/[ERROR] /' or sed 's/^/[ERROR] /' <(cmd) or cmd > >(sed 's/^/[ERROR] /'). But beware the latter. Even that this allows you to access the return value of cmd the sed runs in background, so it is likely you see the output after cmd finished. Good for logging into a file, though. And note that awk probably is faster than sed.
– Tino
Feb 21 '14 at 23:41
alias lpad="sed 's/^/ /'". instead of ERROR I insert 4 leading spaces. Now, for the magic trick: ls | lpad | pbcopy will prepend ls output with 4 spaces which marks it as Markdown for code, meaning that you paste the clipboard (pbcopy grabs it, on macs) directly into StackOverflow or any other markdown context. Couldn't alias the awk answer (on 1st try) so this one wins. The while read solution is also alias-able, but I find this sed more expressive.
– JL Peyret
Dec 08 '17 at 19:59
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,'
awk -v T="[TEST %Y%m%d-%H%M%S] " '{ print strftime(T) $0 }' to output a timestamp
– Tino
Feb 22 '14 at 04:58
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.
>( subshells that I couldn't quite resolve. It seemed as though the script was completing, and the output was arriving to the terminal after the prompt had returned which was a bit messy. I eventually came up with the answer here http://stackoverflow.com/a/25948606/409638
– robert
Sep 20 '14 at 12:20
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...
cmdin this case? – Someone Aug 26 '21 at 23:40