【问题标题】:'find' with 'xargs' and 'tar'使用“xargs”和“tar”“查找”
【发布时间】:2012-07-17 11:08:44
【问题描述】:

我有以下我想做的事情:

find . -maxdepth 6 \( -name \*.tar.gz -o -name bediskmodel -o -name src -o -name ciao -o -name heasoft -o -name firefly -o -name starlink -o -name Chandra \) -prune -o -print | tar  cvf somefile.tar --files-from=-

即,排除一大堆东西,只查看六个子目录深度,然后修剪完成后,将其余部分“tar”起来。

这并不难。管道 (|) 之前的位 100% 工作。如果我排除了“焦油”,那么我就会得到我想要的(在屏幕上)。但是,一旦我包含了管道和焦油,它就会对所有内容进行焦油化,包括我刚刚在“查找”中排除的所有内容。

我尝试了许多不同的迭代:

-print0 | xargs -0 tar rvf somefile.tar
-print0 | xargs -0 tar rvf somefile.tar --null --files-from=-
-print0 | tar cvf somefile.tar --null -T -

那我做错了什么?我以前做过这个;但现在它只是让我白发苍苍。

【问题讨论】:

  • 我相信您需要在 *.tar.gz 周围加上引号,以避免它在传递给 find 之前被 bash 扩展

标签: find tar xargs


【解决方案1】:

-print 标志的组合用于查找,然后 --files-from 在“tar”命令上对我有用。在我的情况下,我需要压缩 5000 多个日志文件,但仅使用“xargs”只会在结果文件中给我 500 个文件。

find . -name "*.pdf" -print | tar -czf pdfs.tar.gz --files-from -

您有“--files-from=-”,而您只需要“--files-from -”,然后我认为您需要在 cvf 前面加上 -,如下所示。

find . -maxdepth 6 ( -name *.tar.gz -o -name bediskmodel -o -name src -o -name ciao -o -name heasoft -o -name firefly -o -name starlink -o -name Chandra ) -prune -o -print| tar -cvf somefile.tar.gz --files-from -

【讨论】:

  • 这是正确的解决方案,因为使用 --files-from - 可以避免导致存档不完整的 xargs 限制问题(在 @rajshenoy 示例的 cmets 中明确)。
【解决方案2】:

我记得我做了类似下面一行的操作来将一堆文件“tar”在一起。我对要分组的文件很明确,所以我运行了这样的内容:

find . -name "*.xyz" | xargs tar cvf xyz.tar;

在您的情况下,我想知道您为什么在 -print 似乎再次包含所有内容之前执行“-o”。

【讨论】:

  • 如果我错了请纠正我,但我相信如果你有很多由find 输出的文件,xargs 将使用文件列表的子集多次运行tar。不幸的是,-c 会覆盖之前的 tar 文件,您只能得到最终 tar 文件中的最后一批。
  • 你可以试试。我成功获得了一个包含 7-8 个文件的 tar 文件,我使用 find 进行了搜索。这里发生的是,Find 返回输出,xargs 将它们提供给 tar 生成单个 tar 文件
  • @jajshenoy 7-8 文件可能不足以发现这个问题。查看this page 中的“最大命令长度”部分。尝试echo | xargs --show-limits 查看 xargs 正在使用的命令行缓冲区的大小 - 对我来说是 131072。这是相当大的,但如果你有几千个文件,它很快就会用完!
  • @Drevicko - 谢谢,你是对的。我会记住这一点
  • @drevicko 这是否意味着我们必须分两步执行此操作?就像用 $(cat mylist) | xargs tar -rf myArchive.tar 构建 tarball 然后 gzip tarball gzip myArchive.tar
【解决方案3】:

如果您的“查找”正在返回目录,那么这些目录将被传递给“tar”,并且无论您的“查找”命令中的排除如何,都会包含完整的内容。

所以,我认为您需要在“查找”中包含“-type f”。

【讨论】:

    【解决方案4】:

    我结合使用前两种方法。为了备份一天的工作,我这样做:

    rm -rf new.tgz; find . -type f -mtime 0 | xargs tar cvf new.tgz;
    

    【讨论】:

      【解决方案5】:

      在没有选项的情况下使用files-from 是让它为我工作的唯一方法。所有其他选项包括目录中的所有文件,而不是我生成的列表。

      这是我的解决方案:

      find . ! -name '*.gz' -print | xargs tar cvzf ../logs.tar.gz --files-from
      

      【讨论】:

      【解决方案6】:

      这适用于我,其中 ARG 可以是任何名称 var

      找到 . -name "*.tar.gz" -print | xargs -I ARG tar -xvzf ARG

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        • 1970-01-01
        • 2013-09-11
        • 2014-12-07
        • 1970-01-01
        • 2018-12-11
        • 1970-01-01
        相关资源
        最近更新 更多