Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 如何一次解压多个文件?_Unix_Shell_Tar - Fatal编程技术网

Unix 如何一次解压多个文件?

Unix 如何一次解压多个文件?,unix,shell,tar,Unix,Shell,Tar,我在一个目录中有一堆tar文件,我想一次从中提取所有文件。但这似乎没有任何作用: $ tar xf *.tar 这是怎么回事?如何一次解压一堆文件?这里发生了什么? 最初,tar命令用于磁带设备。由于一次只能在一个设备上执行tar,因此语法设计为假设一个且只有一个设备。假定传递的第一个文件或目录是保存有问题的归档文件的设备,以及操作中包含归档文件内容的任何其他文件或目录。因此,对于tar提取(x选项),传递的第一个文件将是归档文件,所有其他文件将是要提取的文件。因此,如果有两个*.tar文件(

我在一个目录中有一堆
tar
文件,我想一次从中提取所有文件。但这似乎没有任何作用:

$ tar xf *.tar
这是怎么回事?如何一次解压一堆文件?

这里发生了什么? 最初,
tar
命令用于磁带设备。由于一次只能在一个设备上执行
tar
,因此语法设计为假设一个且只有一个设备。假定传递的第一个文件或目录是保存有问题的归档文件的设备,以及操作中包含归档文件内容的任何其他文件或目录。因此,对于
tar
提取(
x
选项),传递的第一个文件将是归档文件,所有其他文件将是要提取的文件。因此,如果有两个
*.tar
文件(例如
a.tar
b.tar
),您的命令将扩展到:

$ tar xf a.tar b.tar
除非
a.tar
包含名为
b.tar
的文件,否则
tar
命令与此无关,并悄悄退出。令人烦恼的是,Solaris版本的
tar
在返回代码或verbose选项(
v
)中没有报告任何问题。同时,
gnutar
返回
2
和垃圾邮件
STDERR
,即使关闭了verbose选项:

tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors
如何一次解压一堆文件? 重写
tar
来接受多个归档文件作为输入已经太晚了,但是绕过这个限制并不难

对于大多数人来说,为多个归档多次运行
tar
是最方便的选择。只需将一个文件名传递给
tarxf
,即可按预期提取所有存档文件。一种方法是为循环使用shell

$ for f in *.tar; do tar xf "$f"; done
另一种方法是使用
xargs

$ ls *.tar | xargs -i tar xf {}
或者,您可以使用多种方法中的一种。最后,真正专心致志的程序员可以很容易地编写一个完全按照需要工作的
tar
替代品。简单明了,许多编程语言都有库可用于读取
tar
文件。例如,如果您是一名Perl程序员,请查看该模块

警告 盲目地清除一堆文件可能会导致意外问题。最明显的是,一个特定的文件名可能包含在多个
tar
文件中。由于默认情况下,
tar
会覆盖文件,因此最终文件的确切版本将取决于归档文件的处理顺序。更麻烦的是,如果您尝试这种“聪明”的优化,您可能会得到文件的损坏副本:

for f in *.tar; do
  tar xf "$f" &
done
wait
如果
a.tar
b.tar
都包含同一个文件并试图同时提取它,则结果是不可预测的

一个相关的问题,尤其是从不受信任的来源获取档案时,可能会出现错误

一个部分解决方案是自动创建一个新目录以提取到:

for f in *.tar; do 
  d=`basename "$f" .tar`
  mkdir "$d"
  (cd "$d" && tar xf "../$f")
done

如果在归档文件中指定了具有绝对路径的文件(这通常是恶意意图的标志),则这不会有帮助。添加这种检查留给读者作为练习。

如果所有tar文件都在同一个文件夹中,那么我在tcsh shell中执行此操作。一直在工作

find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;
find -iname \*.tar -exec tar -xvf {} \;

这与上面的答案相同,我认为更简洁一些。

我的tar手册页上说,“1997年版本的POSIX标准中出现了-l和-I选项,但2004年版本的标准中没有出现。因此,您应该分别使用-l和-I。”对于这项任务,我会小心使用xargs和“-n1”为了避免最初的问题。@slacy:我想你指的是GNUxargs手册页。我想你是对的,但我真的不喜欢这样的结果:“xargs-I{}tar xf{}”。另一方面,“-n1”在本例中工作良好:“| xargs-n1 tar tf”。这甚至是一种进步。但这对这只老狗来说是个新把戏回答得很好,但我想补充一点,如果其中一个tar包含空格,这将失败,除非我们在tar参数周围加引号:
表示*.tar中的f;do tar xf“$f”;完成
很好的解释!解释代码的作用会很有用!