如何复制目录结构但仅包含某些文件

时间:2011-09-26 04:53:24

标签: bash shell ubuntu

我在Windows中找到了我的问题的解决方案,但我使用的是Ubuntu:How to copy a directory structure but only include certain files using Windows batch files?

正如标题所说,我如何递归复制目录结构但只包含一些文件?例如,给定以下目录结构:

folder1
  folder2
    folder3
      data.zip
      info.txt
      abc.xyz
    folder4
    folder5
      data.zip
      somefile.exe
      someotherfile.dll

文件 data.zip info.txt 可以出现在目录结构的任何位置。如何复制完整的目录结构,但只包含名为data.zipinfo.txt的文件(应忽略​​所有其他文件)?

生成的目录结构应如下所示:

copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip

你能告诉我Ubuntu的解决方案吗?

4 个答案:

答案 0 :(得分:4)

dir3

要排除--include,无论它在树中的位置(即使它包含与--exclude 'dir3/' (before `--filter`) 匹配的文件):

dir3

要仅在树中的特定位置排除--exclude '/dir1/dir2/dir3/' (before `--filter`) ,请从源目录开始指定绝对路径:

dir3

仅在dir2中排除dir2,但无论--exclude 'dir2/dir3/' (before `--filter`) 位于何处,都要排除:{/ p>

*

通配符也可用于路径元素,其中**表示具有任何名称的目录,rsync表示多个嵌套目录。

要仅指定要包含的文件和目录,请运行两个rsync,一个用于文件,另一个用于dirs。在单个rsync中完成此操作的问题在于,当您不包含目录时,$ rsync --recursive --prune-empty-dirs --include="*.txt" --filter="-! */" dir_1 copy_of_dir_1 $ rsync --recursive --include '/dir1/dir2/' --include '/dir3/dir4/' --filter="-! */" dir_1 copy_of_dir_1 无法输入目录,因此无法发现任何文件在该分支中可能与您的包含过滤器匹配。因此,您首先要复制所需的文件,而不是创建任何空的目录。然后复制你想要的任何目录。

$ rsync --recursive --prune-empty-dirs --include="*.txt" --include '/dir1/dir2/' --include '/dir3/dir4/' --filter="-! */" dir_1 copy_of_dir_1

如果您不清楚指定的目标,如果它们被清空则不会被复制,您可以将这些结合起来:

--filter="-! */"

--include是必需的,因为rsync包含的所有文件和文件夹都不匹配任何过滤器(想象它是过滤器列表末尾的不可见rsync过滤器)。 --include根据过滤器列表检查要复制的每个项目,并根据找到的第一个匹配项包含或排除该项目。如果没有匹配,则会触及隐身--exclude并继续包含该项目。我们想将此默认值更改为-,因此我们添加了排除过滤器(-! */中的!),然后我们否定匹配(*/)并匹配所有目录(rsync)。由于这是一个否定的匹配,结果是我们允许rsync输入所有目录(正如我之前提到的那样,允许--filter找到我们想要的文件。)

我们使用--exclude代替--exclude进行最终过滤,因为!不允许指定与$("#paper4").click(function() { if ($("#joinbox").css("margin-top")=="7%") {$("#joinbox").velocity({"margin-top": "-19%"}, 200, "easeInOutQuad");} else {$("#joinbox").velocity({"margin-top": "7%"}, 200, "easeInOutQuad");} }); 运算符的否定匹配。

答案 1 :(得分:1)

我没有一个漂亮的衬垫,但是因为没有其他人回答你总能:

find . -name 'file_name.extension' -print | cpio -pavd /path/to/receiving/folder

复制目录后的每个特定文件。

(当然首先确保你在原始文件夹中!:))

答案 2 :(得分:1)

这是使用rsync的单行:

 rsync -a -f"+ info.txt" -f"+ data.zip" -f'-! */' folder1/ copy_of_folder1/

如果您已有文件列表,并希望获得更具伸缩性的解决方案

 cat file.list | xargs -i rsync -a -f"+ {}" -f'-! */' folder1/ copy_of_folder1/

答案 3 :(得分:0)

cp -pr folder1 copy_of_folder1; find copy_of_folder1 -type f ! \( -name data.zip -o -name info.txt \)  -exec rm -f {} \;
  • 第一次:将folder1完全复制到copy_of_folder1
  • 第二次:擦除data.zip和中的所有文件 info.txt
  • 最后,您的完整结构只包含文件data.zip和info.txt