Reputation: 4718
I have some legacy bash
code that I am running and want to insert print statements which should go to stdout. I want anything that would have gone to stdout to go to out.out
and anything that would have gone to stderr to go to err.err
.
Running myCode.sh 2> err.err 1> out.out
will print everything out as normal, but I'd like to put in print statements like echo "NewStatement: I am at this point in the code"
and then somehow pre-grep for NewStatement
and send it to stdout, while everything else gets treated as normal.
In essence I would like to:
1) Send anything in stdout
containing NewStatement
to stdout
2) Send anything in stdout
not containing NewStatement
to out.out
3) Send anything in stderr
to err.err
is this possible?
Upvotes: 0
Views: 97
Reputation: 7005
It is very easy. First, the "beginner" solution.
Create a wrapper
script (or wrapper function in your main script) which will contain something like this :
#!/bin/bash
while read line || [[ $line ]]
do
if
[[ $line =~ NewStatement ]]
then
echo "$line"
else
echo "$line" >> out.out
fi
done< <("$@" 2>err.err)
Then, simply call your script like this (assuming everything is executable and in the current directory :
./wrapper myCode.sh
The mode "advanced" solution uses a file descriptor to open the target file for writing.
#!/bin/bash
exec 3> out.out # Open file descriptor 3 for writing to file
while read line || [[ $line ]]
do
if
[[ $line =~ NewStatement ]]
then
echo "$line"
else
echo "$line" >> &3
fi
done< <("$@" 2>err.err)
exec 3>&- # Close file descriptor
You could have many file descriptors to perform output to many separate files based on arbitrary complex conditions.
Upvotes: 0
Reputation: 63952
Alternatively, you can
myCode.sh 2>err.err | tee >(grep -v NewStatement > out.out) | grep NewStatement
The tee
duplicates everything from his stdin
, so
grep -v patt
(e.g. doesn't contain) and redirectedstdout
if filtered by grep patt
(e.g. only lines when contain)This can be repeated any times, like
cmd | tee >(cmd1) >(cmd2) >(cmd3) | cmd
Upvotes: 1
Reputation: 785631
You can do it like this:
>out.out
./myCode.sh 2> err.err 1> >(awk '!/^NewStatement/{print > "out.out"; next} 1')
awk
command inside process substitution prints to out.out
if line doesn't start with NewStatement
. Otherwise lines starting with NewStatement
are printed to stdout
.
Upvotes: 1