如何使用 tar 提取没有文件夹结构的文件

Posted

技术标签:

【中文标题】如何使用 tar 提取没有文件夹结构的文件【英文标题】:How do I extract files without folder structure using tar 【发布时间】:2013-01-12 17:14:46 【问题描述】:

我有一个 tar.gz 文件,其结构如下:

folder1/img.gif
folder2/img2.gif
folder3/img3.gif

我想提取没有文件夹层次结构的图像文件,因此提取的结果如下所示:

/img.gif
/img2.gif
/img3.gif

我需要结合 Unix 和 php 来执行此操作。这是我到目前为止所拥有的,它可以将它们提取到指定的目录但保留文件夹层次结构:

exec('gtar --keep-newer-files -xzf images.tgz -C /home/user/public_html/images/',$ret);

【问题讨论】:

我假设您想要的不是手动迭代每个目录、将文件移动到您的路径并删除空文件夹?我不知道任何地方都隐藏了--flatten 选项,但我可能弄错了。 【参考方案1】:

您可以使用 tar 的 --strip-components 选项。

 --strip-components count
         (x mode only) Remove the specified number of leading path ele-
         ments.  Pathnames with fewer elements will be silently skipped.
         Note that the pathname is edited after checking inclusion/exclu-
         sion patterns but before security checks.

我创建了一个与你的结构相似的 tar 文件:

$tar -tf tarfolder.tar
tarfolder/
tarfolder/file.a
tarfolder/file.b

$ls -la file.*
ls: file.*: No such file or directory

然后通过做提取:

$tar -xf tarfolder.tar --strip-components 1
$ls -la file.*
-rw-r--r--  1 ericgorr  wheel  0 Jan 12 12:33 file.a
-rw-r--r--  1 ericgorr  wheel  0 Jan 12 12:33 file.b

【讨论】:

strip-components 是否有您可以使用的最大数量?如果 .tar 仅包含一个文件夹的层次结构但 strip-components 为 2,会发生什么?此外,strip-components 是否会更改这些图像文件的名称或只是删除文件夹? 我建议你试试看它是否适合你。 我尝试使用比包含的目录结构更高的数字,它也删除了文件。所以你必须知道要剥离的目录的确切数量。 这太棒了!但是只有一件事,如果我们不知道要剥离多少组件怎么办?我们只想获取文件而不获取文件夹? 警告:如果有一个没有子文件夹的文件夹(已经是平面的),这意味着没有提取任何内容 --> 所以在将它应用到有和没有结构的文件夹的混合时要小心【参考方案2】:

几乎可以单独使用 tar,使用 --transform 标志,但据我所知无法删除剩余的目录。

这将使整个存档变平:

tar xzf images.tgz --transform='s/.*\///'

输出将是

folder1/
folder2/
folder3/
img.gif
img2.gif
img3.gif

不幸的是,您将需要使用另一个命令删除目录。

【讨论】:

在 RHEL 6.2 上,accepted answer 不起作用,但这个答案确实有效(即使在 创建 存档时)。 :) 耶! 我一直在寻找这个。做得好!如果我根本不想要任何文件夹而只想要提取文件怎么办? 这很棒。截至目前(1.29 版),它甚至不会在提取过程中创建目录。 tar 1.23 也没有创​​建目录。【参考方案3】:

检查 tar 版本,例如

$ tar --version

如果版本是 >= 而不是 tar-1.14.90 使用 --strip-components

tar xvzf web.dirs.tar.gz -C /srv/www --strip-components 2

否则使用--strip-path

tar xvzf web.dirs.tar.gz -C /srv/www --strip-path 2

【讨论】:

【参考方案4】:

基于@ford 的回答。这会将其解压缩到 my_dirname 文件夹。这样我们就可以在不影响现有文件的情况下正确清除空文件夹。

tar xzf images.tgz --transform='s/.*\///' -C my_dirname
find my_dirname -type d -empty -delete

【讨论】:

【参考方案5】:

在mytar.tar.gz的任意子文件夹中找到img*.gif并解压到./

tar -zxf mytar.tar.gz --absolute-names --no-anchored img*.gif --transform='s:.*/::'

在 mytar.tar.gz 中此特定问题中列出的 3 个文件夹中的任何一个中查找 img*.gif 并解压缩到 ./

tar -zxf mytar.tar.gz --absolute-names --no-anchored img*.gif --transform='s:^folder[1-3]/::'

【讨论】:

以上是关于如何使用 tar 提取没有文件夹结构的文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有目录结构的情况下使用 tar 归档来自不同目录的文件

如何获取归档在 tar 中的文件(和其他属性)的创建时间?

如何提取 filename.tar.gz 文件

使用 PHP,我如何识别(如果适用,解压缩)并从 .tar、.gz、.tar.gz、.zip 文件中提取文件?

在 Ruby 中,如何将 tar 归档流直接提取到文件系统?

如何在没有一些文件夹的情况下创建 tar 存档?