Именование файла с использованием содержимого вывода терминала

Именование файла с использованием содержимого вывода терминала

Эта темаздесьобсуждали, как вывести содержимое терминала в файл. В частности, вот с этим:

command |& tee output.txt

Вопрос: возможно ли использовать часть выходного содержимого для наименования файла. Например, предположим, что содержимое распечатывается построчно следующим образом:

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

Можно ли использовать содержимое последней строки для имени файла, а не out.txtв командной строке? Какая-то переменная, может быть? Здесь предполагается, что последняя строка определяется как та, которая появляется непосредственно перед закрытием файла (и завершением выполнения команды).

решение1

Как бы вы ни решили эту проблему, вам придется буферизировать вывод команды, пока вы не сможете прочитать последнюю строку, чтобы знать, куда ее записать.

Единственный разумный способ, который я могу придумать, — это использовать временный файл, а затем переименовать его:

tmpfile=$(mktemp)
outfile=$(command | tee "$tmpfile" | tail -n 1)
mv "$tmpfile" "$outfile"

Вы можете изменить |на , |&если вы действительно хотите захватывать как stdout, так и stderr, но учтите, что этоможетпривести к присвоению выходному файлу имени, соответствующего сообщению об ошибке (хотя, вероятно, есть способ избежать этого, используя умный файловый дескриптор fu).

Возможно, можно реализовать альтернативное решение с помощью spongeкоманды (из пакета moreutils), но, скорее всего, это будет использовать ту же технику под капотом. На самом деле, страница руководства говорит

   When possible, sponge creates or updates the output file atomically by
   renaming a temp file into place.

Другой вариант — использовать revдля перестановки строк, чтобы можно было сначала прочитать последнюю строку, а затем revснова восстановить порядок вывода. Однако это подразумевает буферизацию всего выводадважды.

Связанный контент