Este tópicoaquidiscutimos como enviar o conteúdo do terminal para um arquivo. Particularmente, com isso:
command |& tee output.txt
Pergunta: é possível utilizar parte do conteúdo de saída para nomear o arquivo. Por exemplo, suponha que o conteúdo seja impresso linha por linha da seguinte forma:
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
É possível usar o conteúdo da última linha para nomear o arquivo, em vez de out.txt
na linha de comando? Algum tipo de variável, talvez? Aqui, presume-se que a última linha seja definida como aquela que aparece logo antes do arquivo ser fechado (e o comando terminar de ser executado).
Responder1
Independentemente de como você resolver isso, você terá que armazenar em buffer a saída do comando até poder ler a última linha, para saber onde escrevê-la.
A única maneira sensata de fazer isso é usar um arquivo temporário e renomeá-lo:
tmpfile=$(mktemp)
outfile=$(command | tee "$tmpfile" | tail -n 1)
mv "$tmpfile" "$outfile"
Você pode mudar |
para |&
se realmente deseja capturar stdout e stderr - mas esteja ciente de que issopoderiaresulta na nomeação do arquivo de saída após uma mensagem de erro (embora provavelmente haja uma maneira de evitar isso usando o descritor de arquivo inteligente fu).
Pode ser possível implementar uma solução alternativa usando o sponge
comando (de package moreutils
), mas isso provavelmente usa a mesma técnica nos bastidores. Na verdade, a página de manual diz
When possible, sponge creates or updates the output file atomically by renaming a temp file into place.
Outra opção pode ser rev
inverter as linhas para que você possa ler a última linha primeiro e depois rev
novamente para restaurar a ordem de saída. No entanto, isso envolve armazenar em buffer toda a saídaduas vezes.