通常我会做类似的事情:
tar -czf archive.tar.gz *.csv
但是当目录中的文件太多,以致于 shell 无法在一行上展开时,这种方法就行不通了。
在这些情况下,我通常会使用find
。例如:
find /path -name '*.csv' -exec tar -rf "./archive.tar.gz" {} +;`
但这似乎只有在我不包含该-z
选项时才有效,因为您无法附加到压缩档案,并且使用-c
而不是-r
将覆盖第一个档案,因为 find 多次运行 tar。
我能想到的唯一其他解决方案是使用find
(如上所述)创建一个 .tar 文件,然后使用第二个命令对其进行压缩。有没有更好的方法来处理这种情况?
我正在使用 Ubuntu Linux。
答案1
作为一种强大的解决方案,使用find
空字符分隔文件名,然后直接通过管道传输到tar
,这读取以空字符分隔的输入:
find . -maxdepth 1 -name '*.csv' -print0 |
tar -czf archive.tgz --null -T -
这将处理全部正确命名文件名,并且不受文件数量的限制。
用于ls
生成要由另一个程序解析的文件名列表是一种常见的反模式应尽可能避免这种情况。find
可以生成大多数实用程序可以读取或进一步解析的空分隔输出 ( -print0
)。 由于空字符是唯一不能出现在文件名中的字符(/
显然还有 ),因此您始终可以安全地使用它。
答案2
你不能附加到压缩的 tar 文件无需先解压缩。
然而,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
(如果你的文件名中有双引号,这当然会中断,在这种情况下你会得到你应得的。:)