简体   繁体   English

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

[英]How to copy a directory structure but only include certain files

I found a solution for my question in Windows but I'm using Ubuntu: How to copy a directory structure but only include certain files using Windows batch files? 我在Windows中找到了我的问题的解决方案,但我正在使用Ubuntu: 如何复制目录结构但只包含使用Windows批处理文件的某些文件?

As the title says, how can I recursively copy a directory structure but only include some files? 正如标题所说,我如何递归复制目录结构但只包含一些文件? For example, given the following directory structure: 例如,给定以下目录结构:

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

The files data.zip and info.txt can appear everywhere in the directory structure. 文件data.zipinfo.txt可以出现在目录结构的任何地方。 How can I copy the full directory structure, but only include files named data.zip and info.txt (all other files should be ignored)? 如何复制完整的目录结构,但只包含名为data.zipinfo.txt文件(应忽略​​所有其他文件)?

The resulting directory structure should look like this: 生成的目录结构应如下所示:

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

Could you tell me a solution for Ubuntu? 你能告诉我Ubuntu的解决方案吗?

$ rsync --recursive --include="data.zip" --include="*.txt" --filter="-! */" dir_1 copy_of_dir_1

To exclude dir3 regardless of where it is in the tree (even if it contains files that would match the --include s): 要排除dir3无论它在树中的哪个位置(即使它包含与--include s匹配的--include ):

--exclude 'dir3/' (before `--filter`)

To exclude dir3 only at at specific location in the tree, specify an absolute path, starting from your source dir: 要仅在树中的特定位置排除dir3 ,请从源目录开始指定绝对路径:

--exclude '/dir1/dir2/dir3/' (before `--filter`)

To exclude dir3 only when it's in dir2 , but regardless of where dir2 is: 要仅在dir2排除dir3 ,而不管dir2在哪里:

--exclude 'dir2/dir3/' (before `--filter`)

Wildcards can also be used in the path elements where * means a directory with any name and ** means multiple nested directories. 通配符也可用于路径元素,其中*表示具有任何名称的目录, **表示多个嵌套目录。

To specify only files and dirs to include, run two rsync s, one for the files and one for the dirs. 要仅指定要包含的文件和目录,请运行两个rsync ,一个用于文件,另一个用于dirs。 The problem with getting it done in a single rsync is that when you don't include a dir, rsync won't enter the dir and so won't discover any files in that branch that may be matching your include filter. 在单个rsync完成它的问题是,当您不包含目录时, rsync将不会进入目录,因此不会发现该分支中可能与您的包含过滤器匹配的任何文件。 So, you start by copying the files you want while not creating any dirs that would be empty. 因此,您首先要复制所需的文件,而不是创建任何空的目录。 Then copy any dirs that you want. 然后复制你想要的任何目录。

$ 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

You can combine these if you don't mind that your specified dirs don't get copied if they're empty: 如果您不介意如果指定的目录是空的,则可以将它们复制起来:

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

The --filter="-! */" is necessary because rsync includes all files and folders that match none of the filters (imagine it as an invisible --include filter at the end of the list of filters). --filter="-! */"是必要的,因为rsync的包括所有文件和匹配没有过滤条件的文件夹(把它想象成一种无形的--include在过滤器列表的末尾过滤器)。 rsync checks each item to be copied against the list of filters and includes or excludes the item depending on the first match it finds. rsync根据筛选器列表检查要复制的每个项目,并根据找到的第一个匹配项包含或排除该项目。 If there's no match, it hits that invisible --include and goes on to include the item. 如果没有匹配,它击中无形--include并继续列入的项目。 We wanted to change this default to --exclude , so we added an exclude filter (the - in -! */ ), then we negate the match ( ! ) and match all dirs ( */ ). 我们想将此默认值更改为--exclude ,因此我们添加了一个排除过滤器( - in -! */ ),然后我们否定匹配( ! )并匹配所有dirs( */ )。 Since this is a negated match, the result is that we allow rsync to enter all the directories (which, as I mentioned earlier, allows rsync to find the files we want). 由于这是一个否定的匹配,结果是我们允许rsync进入所有目录(正如我之前提到的,它允许rsync找到我们想要的文件)。

We use --filter instead of --exclude for the final filter because --exclude does not allow specifying negated matches with the ! 我们使用--filter而不是--exclude作为最终过滤器,因为--exclude不允许使用!指定否定匹配! operator. 运营商。

Here is a one-liner using rsync: 这是使用rsync的单线程:

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

If you already have a file list, and want a more scalable solution 如果您已有文件列表,并希望获得更具伸缩性的解决方案

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

I don't have a beautiful one liner, but since nobody else has answered you can always: 我没有一个漂亮的衬垫,但是因为没有其他人回答你总能:

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

For each specific file after copying the directories. 复制目录后的每个特定文件。

(Make sure you're in the original folder first, of course! :) ) (当然,请确保您首先在原始文件夹中!:))

cp -pr folder1 copy_of_folder1; find copy_of_folder1 -type f ! \( -name data.zip -o -name info.txt \)  -exec rm -f {} \;
  • first time : copy entirely folder1 to copy_of_folder1 第一次:将folder1完全复制到copy_of_folder1
  • second time : erase all files differents from data.zip and info.txt 第二次:从data.zip和info.txt中清除所有文件的不同
  • At the end, you have your complete structure with only the file data.zip and info.txt 最后,您拥有完整的结构,只有文件data.zip和info.txt

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何`scp`目录保留结构但仅选择某些文件? - How to `scp` directory preserving structure but only pick certain files? rsync 仅使用包含选项复制某些类型的文件 - rsync copy over only certain types of files using include option 复制没有文件的目录结构 - copy directory structure without files BASH:仅从目录复制图像,不复制文件夹结构并按顺序重命名复制的文件 - BASH: copy only images from directory, not copying folder structure and rename copied files in sequential order 如何将某些文件从一个目录移动到另一个目录,同时保持目录结构 - How to move certain files from one directory to another, while maintaining directory structure 如何在一定时间内复制带有一定后缀的文件? - how to copy files with certain suffix for a certain times? 如何在bash中以递归方式将同名文件从一个目录结构复制到另一个目录结构? - How can I recursively copy same-named files from one directory structure to another in bash? 递归移动某种类型的文件并保持它们的目录结构 - Recursively move files of certain type and keep their directory structure 将具有特定扩展名的所有文件复制到另一个目录,同时更改扩展名 - Copy all files with certain extension to another directory, while changing the extension 仅在下面的目录中查找和同名文件,然后复制到其他目录 - Find and files of same name only in directory below and copy to a different directory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM