Naming file using content of terminal output
This thread here discussed how to output terminal content to a file. Particularly, with this:
command |& tee output.txt
Question: is it possible to utilize part of the output content to name the file. For eg., suppose the content is printed out line by line as following:
action_1_last_time_2021_06_15_21_34_56
action_2_last_time_2021_06_15_21_35_23
action_3_last_time_2021_06_15_21_43_45
...
action_320032_last_time_2021_06_15_23_59_14
Is it possible to use the content of the last line to name the file, instead of out.txt
on the command line? Some sort of variable, maybe? Here, the last line is presumed to be defined as one that appears just before the file is closed (and the command finishes running).
Solution 1:
However you solve this, you're going to have to buffer the command output until you can read the last line, in order to know where to write it.
The only sensible way I can think of doing this is to use a temporary file, then rename it:
tmpfile=$(mktemp)
outfile=$(command | tee "$tmpfile" | tail -n 1)
mv "$tmpfile" "$outfile"
You can change |
to |&
if you really want to capture both stdout and stderr - but be aware that this may result in naming the output file after an error message (although there's probably a way to avoid that using clever file descriptor fu).
It may be possible to implement an alternate solution using the sponge
command (from package moreutils
) but that likely uses the same technique under the hood. In fact, the man page says
When possible, sponge creates or updates the output file atomically by renaming a temp file into place.
Another option might be to use rev
to reverse the lines so that you can read the last line first, and then rev
again to restore the output order. However that involves buffering the whole output twice.