端末出力の内容を使用してファイルに名前を付ける

端末出力の内容を使用してファイルに名前を付ける

このスレッドここ端末の内容をファイルに出力する方法について説明しました。特に、次の点について:

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の両方をキャプチャしたい場合は、|に変更することができますが、これは|&5月結果的に、出力ファイルの名前がエラー メッセージにちなんで付けられます (ただし、巧妙なファイル記述子 fu を使用してこれを回避する方法はおそらくあります)。

spongeコマンド(パッケージから)を使用して別の解決策を実装することは可能かもしれませんmoreutilsが、それはおそらく裏で同じテクニックを使用しています。実際、manページには次のように書かれています。

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

revもう一つの選択肢は、行を逆にして最後の行を最初に読み、その後revもう一度出力順序を復元することです。ただし、出力全体をバッファリングする必要があります。2回

関連情報