appending data to last line of file

A friend contacted me recently with an interesting question. We got something worked out, but I'm curious what answers you all can come up with.

Given a shell script (in bash) that processes a bunch of data and appends it to a file, how would you append the date, time, and a filename to the last line of the output?

Example:

output file:

355.355 234.123. 229.812
355.355 234.153. 229.815
355.335 234.123. 229.812

Desired output

355.355 234.123. 229.812
355.355 234.153. 229.815
355.335 234.123. 229.812 06/21/10 00:12:43 data.txt

Assume further that this has to happen separately from the part of the script that actually produces the data. It's a function that someone else wrote, and can't be changed. For what it's worth, I first suggested that some sort of time/date/file block be added at the start of the data file. But the requirements above are what my friend wanted, so that's the question.

Like this?

sed '$s/.*/& here comes your text/' infile
355.355 234.123. 229.812
355.355 234.153. 229.815
355.335 234.123. 229.812 here comes your text
1 Like

Ahh, nice. I should have said "end up with it appended to the same data file that you're writing in the first place.

So, in pseudocode:

while (still have some input to handle)
     generate_data() # writes to data1.txt

# ok we're done, add the date stamp
(some sort of sed magic) >> data1.txt

Something like this? Keeping the original date of the file:

[ "$1" != "" ] || exit 1
timestamp=$(ls -l "$1" | awk '{print $6,$7}' )
sed '$s|.*|& '"$timestamp ${1##*/}|" "$1" > "$1.$$" && touch -d "$timestamp" "$1.$$" && mv -f "$1.$$" "$1"

More precise with GNU versions:

[ "$1" != "" ] || exit 1
timestamp=$(ls -l --full-time "$1" | awk '{print $6,$7}' )
sed -i '$s|.*|& '"$timestamp ${1##*/}|" "$1" && touch -d "$timestamp" "$1"

If you have GNU sed you could use -i to edit the file directly.

Very nice. Thanks to all who contributed.

I had forgotten (if I ever knew) that you could use $ as a line marker.

#!/bin/sh

f=$1

ed -s "$f" <<EOED
a
 $(date +'%D %T') $f
.
-,.j
w
q
EOED

If you prefer a less readable but more compact (on screen) approach, the following is equivalent:

printf 'a\n %s %s\n.\n-,.j\nw\nq\n' "$(date +'%D %T')" "$f" | ed -s "$f"

Regards,
Alister