Prepending a timestamp to each line of output from a command
moreutils includes ts
which does this quite nicely:
command | ts '[%Y-%m-%d %H:%M:%S]'
It eliminates the need for a loop too, every line of output will have a timestamp put on it.
$ echo -e "foo\nbar\nbaz" | ts '[%Y-%m-%d %H:%M:%S]'
[2011-12-13 22:07:03] foo
[2011-12-13 22:07:03] bar
[2011-12-13 22:07:03] baz
You want to know when that server came back up you restarted? Just run ping | ts
, problem solved :D.
Firstly, if you are expecting these timestamps to actually represent an event, bear in mind that since many programs perform line buffering (some more aggressively than others), it is important to think of this as close to the time that the original line would have been printed rather than a timestamp of an action taking place.
You may also want to check that your command doesn't already have an inbuilt feature dedicated to doing this. As an example, ping -D
exists in some ping
versions, and prints the time since the Unix epoch before each line. If your command does not contain its own method, however, there are a few methods and tools that can be employed, amongst others:
POSIX shell
Bear in mind that since many shells store their strings internally as cstrings, if the input contains the null character (\0
), it may cause the line to end prematurely.
command | while IFS= read -r line; do printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done
GNU awk
command | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'
Perl
command | perl -pe 'use POSIX strftime; print strftime "[%Y-%m-%d %H:%M:%S] ", localtime'
Python
command | python -c 'import sys,time;sys.stdout.write("".join(( " ".join((time.strftime("[%Y-%m-%d %H:%M:%S]", time.localtime()), line)) for line in sys.stdin )))'
Ruby
command | ruby -pe 'print Time.now.strftime("[%Y-%m-%d %H:%M:%S] ")'
For a line-by-line delta measurement, try gnomon.
It is a command line utility, a bit like moreutils's ts, to prepend timestamp information to the standard output of another command. Useful for long-running processes where you'd like a historical record of what's taking so long.
Piping anything to gnomon will prepend a timestamp to each line, indicating how long that line was the last line in the buffer--that is, how long it took the next line to appear. By default, gnomon will display the seconds elapsed between each line, but that is configurable.