【问题标题】:Bash - How can I archive and compress files in subdirectories but only with a certain filenameBash - 我如何归档和压缩子目录中的文件,但只能使用特定的文件名
【发布时间】:2014-08-24 03:32:40
【问题描述】:

我的目录结构如下:

main_directory/
    directory1:
        sub_directory1:
            files:
                myfile.txt
                otherfile.txt
        sub_directory2:
            files:
                myfile.txt
                otherfile.txt
        sub_directory3:
            files:
                myfile.txt
                otherfile.txt
        sub_directory4:
            files:
                myfile.txt
                otherfile.txt
    directory2:
        sub_directory1:
            files:
                myfile.txt
                otherfile.txt
        sub_directory2:
            files:
                myfile.txt
                otherfile.txt
        sub_directory3:
            files:
                myfile.txt
                otherfile.txt
        sub_directory4:
            files:
                myfile.txt
                otherfile.txt

我试图弄清楚(通过反复试验,因为我不是 Linux 专家)如何仅 gzip 所有目录中的 myfile.txt 文件。由于它们在不同的路径中都有相同的文件名(没有办法解决这个问题),我还需要能够将文件路径保留在存档中。所以我要创建的最终 gzipped tar 文件将包含以下内容:

mytar.tar.gz
    main_directory/directory1/sub_directory1/files/myfile.txt
    main_directory/directory1/sub_directory2/files/myfile.txt
    main_directory/directory1/sub_directory3/files/myfile.txt
    main_directory/directory1/sub_directory4/files/myfile.txt
    main_directory/directory2/sub_directory1/files/myfile.txt
    main_directory/directory3/sub_directory2/files/myfile.txt
    main_directory/directory4/sub_directory3/files/myfile.txt
    main_directory/directory5/sub_directory4/files/myfile.txt

有没有简单的bash 方法来做到这一点?我想我可以编写一个python 脚本来完成它,但这似乎有点过头了。

有人有什么建议吗?

【问题讨论】:

    标签: linux bash gzip tar


    【解决方案1】:

    这克服了另一个答案中描述的这个问题。

    find main_directory/ -name "myfile.txt" | tar -czvf mytar.tar.gz -T -
    

    【讨论】:

      【解决方案2】:

      假设没有太多文件,你可以这样做:

      cd main_directory/..
      find main_directory -name "myfile.txt" | xargs tar zcf mytar.tar.gz
      

      如果有很多文件,您可以将文件列表通过管道传输到文件/流中并将其传递给 tar。

      find main_directory -name "myfile.txt" -print0 | tar zcf myar.tar.gz --null -T -
      

      这会打印出由空值分隔的文件名(-print0find)并指示 tarstdin 正确解析;使用 null 可确保正确处理目录中的任何特殊字符

      【讨论】:

      • 太棒了。谢谢!太棒了。我想我需要更多地了解管道:-)
      • 如果文件数量太大而导致 xargs 无法构建命令行,这将非常糟糕,因为它将多次运行 tar 并覆盖自身(或失败)。最好使用 tar 的 -T 参数告诉它从文件中获取要归档的文件列表并告诉它使用 /dev/stdin 或类似的(或者只是写入文件然后将其传递给 @ 987654330@.
      • 是的,刚刚碰到这个。抱歉过早的反应......看起来它工作得非常好。我想我的文件太多(大约 1000 个)。只有少数几个实际上包含在最终的 tar 中。
      • 我看到你想通了-T;更新了我的答案以包含该问题以及处理文件名中的换行符或空值或其他特殊字符的技巧。
      【解决方案3】:

      使用足够新的(我相信是 4.0.0+)版本的 bash(以及许多其他 shell),以下内容将起作用:

      tar -czf mytar.tar.gz main_directory/**/myfile.txt
      

      【讨论】:

      • 如果globstar(和dotglob)打开,它会工作,但它仍然会命中ARG_MAX,并且在大量文件上失败。
      • 确实如此。我本想提到globstar,但设法忘记了。是的,命令行长度问题仍然是一个问题,但这里的失败并不像@EmilSit 的情况那么糟糕,因为它最终没有截断(但显然是完整的)tarball(或错误进入tar 进程),而是立即出错。
      【解决方案4】:

      如果目录结构确实是这个规则,通配符

      main_directory/*/*/files/myfile.txt
      

      将匹配您想要的文件。但是,如果文件很多,您可能需要恢复到find / xargs 以避免“参数列表太长”(ARG_MAX)的问题。

      如果您不想包含名为myfile.txt 的文件,因为它们的路径与通配符不完全匹配,当然也有办法将它们从find 中排除;也许那么这个额外的约束应该在问题中说明。

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        • 2015-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多