首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何复制目录结构,但只包含某些文件

如何复制目录结构,但只包含某些文件
EN

Stack Overflow用户
提问于 2011-09-26 04:53:23
回答 4查看 4K关注 0票数 5

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

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

代码语言:javascript
复制
folder1
  folder2
    folder3
      data.zip
      info.txt
      abc.xyz
    folder4
    folder5
      data.zip
      somefile.exe
      someotherfile.dll

文件data.zipinfo.txt可以在目录结构中随处可见。如何复制完整的目录结构,但只包含名为data.zipinfo.txt的文件(应该忽略所有其他文件)?

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

代码语言:javascript
复制
copy_of_folder1
  folder2
    folder3
      data.zip
      info.txt
    folder4
    folder5
      data.zip

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-26 06:39:11

我没有一条漂亮的衬垫,但既然没有其他人回答你,你永远可以:

代码语言:javascript
复制
find . -name 'file_name.extension' -print | cpio -pavd /path/to/receiving/folder

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

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

票数 4
EN

Stack Overflow用户

发布于 2015-11-03 02:49:23

代码语言:javascript
复制
$ rsync --recursive --include="data.zip" --include="*.txt" --filter="-! */" dir_1 copy_of_dir_1

要排除dir3,不管它在树中的位置(即使它包含的文件将与--include的文件匹配):

代码语言:javascript
复制
--exclude 'dir3/' (before `--filter`)

若要仅在树中的特定位置排除dir3,请指定一个绝对路径,从源dir开始:

代码语言:javascript
复制
--exclude '/dir1/dir2/dir3/' (before `--filter`)

仅当dir3dir2中时才排除它,但不管dir2在哪里:

代码语言:javascript
复制
--exclude 'dir2/dir3/' (before `--filter`)

通配符也可以在path元素中使用,其中*表示具有任意名称的目录,而**表示多个嵌套目录。

若要仅指定要包含的文件和dirs,请运行两个rsync,一个用于文件,另一个用于dirs。在单个rsync中完成它的问题是,当您不包含dir时,rsync不会输入dir,因此不会在该分支中发现任何可能与包含过滤器匹配的文件。因此,首先要复制所需的文件,而不是创建任何空的dir。然后复制你想要的任何脏东西。

代码语言:javascript
复制
$ 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

如果您不介意在指定的mind为空时不会复制它们,则可以将它们组合在一起:

代码语言:javascript
复制
$ rsync --recursive --prune-empty-dirs --include="*.txt" --include '/dir1/dir2/' --include '/dir3/dir4/' --filter="-! */" dir_1 copy_of_dir_1

--filter="-! */"是必要的,因为rsync包含不匹配任何过滤器的所有文件和文件夹(假设它是过滤器列表末尾的不可见--include过滤器)。rsync根据筛选器列表检查要复制的每一项,并根据它找到的第一次匹配包括或排除该项。如果没有匹配,它就会击中那个不可见的--include并继续包含该项目。我们希望将此默认值更改为--exclude,因此添加了一个排除筛选器(-! */中的- ),然后取消匹配(!)并匹配所有dir (*/)。由于这是一个被否定的匹配,因此我们允许rsync输入所有目录(正如我前面提到的,这允许rsync找到我们想要的文件)。

对于最终的筛选器,我们使用--filter而不是--exclude,因为--exclude不允许使用!运算符指定被否定的匹配。

票数 5
EN

Stack Overflow用户

发布于 2015-11-05 23:13:33

下面是使用rsync的一行程序:

代码语言:javascript
复制
 rsync -a -f"+ info.txt" -f"+ data.zip" -f'-! */' folder1/ copy_of_folder1/

如果您已经有了一个文件列表,并且希望有一个更可伸缩的解决方案

代码语言:javascript
复制
 cat file.list | xargs -i rsync -a -f"+ {}" -f'-! */' folder1/ copy_of_folder1/
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7550773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档