如何复制所有文件,同时排除具有特定模式的文件?

如何复制所有文件,同时排除具有特定模式的文件?

我有以下文件夹和文件:

.
├── photos
│   ├── photo-a
│   │   ├── photo-a.meta.json
│   │   └── photo-a.json
│   ├── photo-b
│   │   ├── photo-b.meta.json
│   │   └── photo-b.json
...
There are more folders and files in the photos folder in the same structure

我想将所有文件和其他文件复制photo-a.jsonphoto-b.json另一个名为photos-copy.基本上,我想排除所有以 files 结尾的文件.meta.json,但仅复制以 files 结尾的文件.json

因此,如果操作正确,photos-copy文件夹将如下所示:

.
├── photos-copy
│   ├── photo-a.json
│   └── photo-b.json
...

我尝试了一些方法cp -a ./photos/*.json ./photos-copy,但这最终会复制所有内容,因为.meta.json文件也以扩展名结尾.json

我怎样才能做到这一点?

答案1

我想到了几个选择。

rsync --dry-run -av --prune-empty-dirs --exclude '*.meta.json' --include '*.json' photos/ photos-copy/

或者,如果您没有rsync(为什么不!?),这将复制保留结构的文件

cp -av photos/ photos-copy/
rm -f photos-copy/*/*.meta.json

此变体会将文件平铺到单个目录中

cp -av photos/*/*.json photos-copy/
rm -f photos-copy/*.meta.json

您可以使用bash它的扩展模式匹配来做更多奇特的事情,它告诉 shell 匹配.meta其名称中不包含的所有内容:

shopt -s extglob
cp -av photos/*/!(*.meta).json photos-copy/

答案2

使用 rsync:rsync -rv --include="*/" --exclude="*.meta.json" --include "*.json" --exclude="*" ./photos/ photo-copy/

原来的目录结构:

photo-a/photo-a.json
photo-a/photo-a.meta.json
photo-b/photo-b.json
photo-b/photo-b.meta.json
photo-b/photo-b.son

输出:

sending incremental file list
photo-a/photo-a.json
photo-b/photo-b.json

我用之前的答案(rsync --dry-run -av --prune-empty-dirs --exclude '*.meta.json' --include '*.json' photos/ photos-copy/)输出尝试了它:

photo-a/photo-a.json
photo-b/
photo-b/photo-b.json
photo-b/photo-b.son

说明:在 rsync 中包含/排除顺序很重要。首先包括所有子目录。排除 meta.json、包含 .json,并排除其他任何内容。

相关内容