Put a text in front of every new line that a program prints to stdout
So I want to do some logging and therefor, want to put a date in front of a bash script's output. The problem is that is has multiple lines of output. I am able to only put the date before the whole output. But then I have a line without a date in the logs. Of course I can assume the date from the line above is the same, but I was hoping there is a solution. Thanks in advance!
This is my script that calls another script:
#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended
This is the output:
2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended
And thats what I would like to have:
2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended
Solution 1:
According to a similar question on Stack Overflow, there are 2 great options.
awk (Answer)
<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'
annotate (Answer)
annotate is a small bash script, that can either be directly obtained through the link provided here, or, on Debian based systems, through the package devscripts
(in the form of annotate-output
).
Solution 2:
I think that you can use awk for this:
./script.sh | awk '{ print strftime()" : "$0; }'
(see http://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html for formatting the date returned by strftime())
Solution 3:
You can use awk
./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"
awk
takes an input stream and modifies it's output. This script is saying "print d followed by the original output", then then populates d
with the date.
Solution 4:
This will print the current date and time before each line of output of ./script.sh
:
set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f
How it works
set -f
turns off bash expansion (orecho *
wouldn't print an actual asterisk).while read -r LINE; do ... done
saves one line of output in the variable$LINE
and executes...
, until all lines are processed.echo $(date "+%F %T") : "$LINE" prints the line with the current time and date.
set +f
turns bash expansion back on, so it won't interfere with the rest of your bash script.