使用終端輸出的內容命名文件

使用終端輸出的內容命名文件

這個線程這裡討論如何將終端內容輸出到檔案。特別是,這樣:

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再次恢復輸出順序。然而,這涉及緩衝整個輸出兩次

相關內容