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

Jon*_*son 68 unix shell tar

tar在目录中有一堆文件,我想立即从中提取所有文件.但这似乎没有做任何事情:

$ tar xf *.tar
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?如何一次解压缩一堆文件?

Jon*_*son 134

这里发生了什么?

最初,该tar命令旨在用于磁带设备.由于一次只tar在一个设备上执行是有意义的,因此语法被设计为假设一个且仅有一个设备.传递的第一个文件或目录被假定为持有相关存档的设备以及要包含在操作中的存档内容的任何其他文件或目录.因此,对于tar提取(x选项),传递的第一个文件将是存档,所有其他文件将是要提取的文件.因此,如果有两个*.tar文件(例如a.tarb.tar),您的命令将扩展为:

$ tar xf a.tar b.tar
Run Code Online (Sandbox Code Playgroud)

除非a.tar包含一个名为的文件b.tar,否则该tar命令无关,可以安静地退出.令人讨厌的是,Solaris版本tar在返回代码或verbose选项(v)中都没有报告任何问题.同时,即使关闭详细选项,也会GNU tar返回2并发送垃圾邮件STDERR:

tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors
Run Code Online (Sandbox Code Playgroud)

如何一次解压缩一堆文件?

tar接受多个存档文件作为输入是不太可能的重写,但要解决这个限制并不是很难.

对于大多数人来说,tar多次存档多次运行是最方便的选择.仅传递一个文件tar xf名将提取所有已归档的文件.一种方法是使用shell for循环:

$ for f in *.tar; do tar xf "$f"; done
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用xargs:

$ ls *.tar | xargs -i tar xf {}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用许多替代tar文件读取器之一.最后,真正专业的程序员可以轻松编写一个tar完全符合要求的替换程序.该格式是直接和许多编程语言有可供读取的库tar文件.例如,如果您是Perl程序员,请查看该Archive::Tar模块.

一个警告

盲目解读一堆文件会导致意外问题.最明显的是特定文件名可能包含在多个tar文件中.由于tar默认情况下会覆盖文件,因此您最终获得的文件的确切版本将取决于归档文件的处理顺序.更令人不安的是,如果你尝试这种"聪明"的优化,你可能会得到一个损坏的文件副本:

for f in *.tar; do
  tar xf "$f" &
done
wait
Run Code Online (Sandbox Code Playgroud)

如果两个a.tarb.tar包含相同的文件,并试图在同一时间提取出来,结果是不可预知的.

一个相关的问题,特别是从不受信任的来源获取档案时,可能会出现问题.

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

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

如果在存档中使用绝对路径指定文件(这通常是恶意意图的标志),这将无济于事.添加这种检查留给读者练习.


小智 11

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

find -iname \*.tar -exec tar -xvf {} \;
Run Code Online (Sandbox Code Playgroud)

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


小智 6

find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;
Run Code Online (Sandbox Code Playgroud)

  • 解释代码的作用将很有用! (6认同)