題 當shell的文件名太多而無法在一行上展開時如何製作壓縮tar?


通常我會做的事情如下:

tar -czf archive.tar.gz *.csv

但是當目錄中有太多文件要讓shell在一行上展開時,這不起作用。

在這些情況下,我通常會使用 find。就像是:

find /path -name '*.csv' -exec tar -rf "./archive.tar.gz" {} +;`

但是,如果我不包括這個,那麼這似乎才有用 -z 選項,因為您無法附加到壓縮存檔,並使用 -c 代替 -r 將覆蓋第一個存檔,因為find多次運行tar。

我能想出的唯一其他解決方案是創建一個.tar文件 find (如上所述)然後使用第二個命令來壓縮它。有沒有更好的方法來處理這樣的案件?

我正在使用Ubuntu Linux。


5
2017-09-06 22:30


起源


您可以創建tar存檔並在以後壓縮它。 (過去是我們走上坡路到學校的方式,兩種方式)。 - Hennes
你的find命令會遇到同樣的問題,因為在查找它之前會擴展glob。你應該用 find -name '*.csv' 代替。 - slhck
的確,我現在修好了。 - Code Commander


答案:


作為強大的解決方案,請使用 find 用空字符分隔文件名,然後直接管道到 tar, 哪一個 讀取空分隔的輸入

find . -name '*.csv' -maxdepth 1 -print0 |
tar -czf archive.tgz --null -T -

這將處理 所有 文件名正確,也不受文件數量的限制。

運用 ls 生成要由另一個程序解析的文件名列表 是一種常見的反模式 應該盡可能避免。 find 可以生成以null分隔的輸出(-print0)大多數實用程序可以進一步讀取或解析。由於空字符是唯一不能出現在文件名中的字符(和 /,顯然),你總是那麼安全。


6
2017-09-08 11:23





你不能 附加到壓縮的tar文件 沒有首先解壓縮它。

但是,焦油可以 接受要從文件處理的文件列表,所以你可以這樣做:

ls *.csv > temp.txt
tar -zcf ball.tgz -T temp.txt

@slhck指出,如果文件名中有空格(可能還有其他惱人的字符),上述解決方案將無效。此版本用雙引號括起每個文件名:

ls *.csv | sed -e 's/^\(.*\)$/"\1"/' > temp.txt
tar -zcf ball.tgz -T temp.txt

(如果你的文件名中有雙引號,這當然會中斷,在這種情況下,你得到你應得的。:)


8
2017-09-06 22:38



如果您想在單個命令中執行此操作,則可以使用 tar -zcf ball.tgz -T <( ls *.csv) 要么 tar -zcf ball.tgz -T <( find -name '*.csv')。看到 tldp.org/LDP/abs/html/abs-guide.html#PROCESS-SUB - Zoredache
這不是我想到的解決方案。請參閱我的答案,了解不會阻塞文件名的解決方案。不要責怪用戶在路徑中創建帶空格或雙引號的文件 - 所有Linux工具都可以正確處理,只需要應用正確的選項即可。一般來說,作為一個好的提示,一旦你發現自己使用 ls 枚舉除了以外的文件 看著 對他們來說,有些東西可能會破裂。 - slhck