Эта темаздесьобсуждали, как вывести содержимое терминала в файл. В частности, вот с этим:
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
снова восстановить порядок вывода. Однако это подразумевает буферизацию всего выводадважды.