我在目录中有一堆tar
个文件,我想一次从中提取所有文件。但这似乎没有做任何事情:
$ tar xf *.tar
这里发生了什么?如何一次解压缩一堆文件?
答案 0 :(得分:128)
最初,tar
命令适用于磁带设备。由于一次只在一个设备上执行tar
才有意义,因此语法设计为假设一个且仅有一个设备。传递的第一个文件或目录被假定为持有相关存档的设备以及要包含在操作中的存档内容的任何其他文件或目录。因此,对于tar
提取(x
选项),传递的第一个文件将是存档,所有其他文件将是要提取的文件。因此,如果有两个*.tar
个文件(例如a.tar
和b.tar
),您的命令将扩展为:
$ tar xf a.tar b.tar
除非a.tar
包含名为b.tar
的文件,否则tar
命令无关,并且会安静地退出。令人讨厌的是,Solaris tar
版本不会在返回代码或详细选项(v
)中报告任何问题。同时,GNU tar
即使关闭详细选项,也会返回2
并发送STDERR
:
tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors
重写tar
以接受多个档案文件作为输入已经太晚了,但要解决这个限制并不是很难。
对于大多数人来说,多个档案多次运行tar
是最方便的选择。仅传递一个文件名到tar xf
将提取所有已归档的文件。一种方法是使用shell for
循环:
$ for f in *.tar; do tar xf "$f"; done
另一种方法是使用xargs
:
$ ls *.tar | xargs -i tar xf {}
或者,您可以使用多个alternative tar
file readers中的一个。最后,真正专业的程序员可以轻松地编写一个tar
替换,完全按照需要工作。 format很简单,许多编程语言都有可用于读取tar
文件的库。例如,如果您是Perl程序员,请查看Archive::Tar
模块。
盲目解读一堆文件会导致意外问题。最明显的是特定文件名可能包含在多个tar
文件中。由于tar
默认会覆盖文件,因此您最终获得的文件的确切版本将取决于归档文件的处理顺序。更令人不安的是,如果你尝试这种“聪明”的优化,你可能会得到一个损坏的文件副本:
for f in *.tar; do
tar xf "$f" &
done
wait
如果a.tar
和b.tar
包含相同的文件并尝试同时提取,则结果无法预测。
相关问题,尤其是从不受信任的来源获取档案时,可能是tarbomb。
一个部分解决方案是自动创建一个新目录以提取到:
for f in *.tar; do
d=`basename "$f" .tar`
mkdir "$d"
(cd "$d" && tar xf "../$f")
done
如果在存档中使用绝对路径指定文件(通常是恶意意图的标志),这将无济于事。添加这种检查留给读者练习。
答案 1 :(得分:11)
如果所有tar文件都在同一个文件夹中,那么我在tcsh shell中执行此操作。一直有效。
find -iname \*.tar -exec tar -xvf {} \;
这与上面的答案相同,我认为更简洁一点。
答案 2 :(得分:4)
find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;