18

I would like to have a timestamp printed in front of every line that comes out of a "tail -f outputfile", so that I know when is each line printed in. Something like:

[...]
20110617_070222:results printed here
20110617_070312:results printed here
20110617_070412:results printed here
20110617_070513:results printed here
[...]

Any ideas?

719016
  • 4,177
  • 16
  • 59
  • 91
  • 1
    Note that you aren't getting quite what you asked for. The answers you've received are based upon the assumption that you don't mind the timestamp errors introduced by the fact that these are the times that `tail` writes to its standard output, _not_ the times that the lines were written to the original file in the first place. You may well not mind, but be aware of this assumption derived from your question as it is written. – JdeBP Jun 17 '11 at 12:31
  • 1
    Duplicate question, with good answers: https://unix.stackexchange.com/q/26728/52959 – David Balažic Apr 28 '20 at 10:23

4 Answers4

22

It probably doesn't get any shorter than this:

tail -f outputfile | xargs -IL date +"%Y%m%d_%H%M%S:L"

Note that I used the timestamp format suggested by your question, but you're free to use anything supported by the date command (the format syntax is supported by standard BSD and GNU date).

David Ongaro
  • 346
  • 2
  • 6
  • Note that `xargs` ignores empty lines. For my usecase that's fine but your milage may vary. – David Ongaro Feb 24 '17 at 07:34
  • This will break if xargs encounters unmatched quote `"` in the line. – MarSoft Apr 28 '17 at 20:11
  • 1
    I see. Maybe `tail -f outputfile | tr '\n' '\0' | xargs -0IL date +"%Y%m%d_%H%M%S:L"` is better in this case? Also works with empty lines then. – David Ongaro Apr 28 '17 at 23:54
  • Wouldn't this invoke `date` on each and every output line? – Thorbjørn Ravn Andersen Oct 06 '20 at 10:59
  • @ThorbjørnRavnAndersen That's right. But a few `date` invocations per second shouldn't be a problem on any system. Otherwise you probably should resort to a script or a compiled program. Or if you want to keep it pure bash you can restrict yourself to builtins, e.g.: `tail -f outputfile | while read line; do printf "%(%Y%m%d_%H%M%S)T:%s\n" "$EPOCHSECONDS" "$line"; done`; I didn't do any performance measurements here though. (But if you really need subsecond precision, just prefixing `$EPOCHREALTIME` makes more sense.) – David Ongaro Oct 07 '20 at 08:43
  • @DavidOngaro It is not necessarily a bad thing, but important to know when you are deciding upon which solution is best for you. – Thorbjørn Ravn Andersen Oct 07 '20 at 08:45
6

Write a simple script to do that. Here's an example in perl:

#!/usr/bin/perl
while(<>) {
    print localtime . ": $_";
}

To use the script, simply pipe your tail output through it:

tail -f outputfile | ./prepend_timestamp.pl

You could also do it inline:

tail -f outputfile | perl -pe '$_ = localtime.": $_"'
Flimzy
  • 4,374
  • 21
  • 41
1

I would normally do this with perl as answered by others, but it was unavailable at the rather trimmed down Linux machine where I needed it, but the busybox awk applet was!

tail -f some_file  | awk -e '{ print strftime("%Y%m%d_%H%M%S",systime()) "\t" $0}'

As always the timestamp is for when the line was printed, not when it was written originally.

0

With awk:

tail -f infile | awk '{"date \"+%Y%m%d_%H%M%S\"" | getline now} {close("date")} {print now ": " $0}'
Prince John Wesley
  • 2,797
  • 2
  • 21
  • 13