我有一个目录l
── 10020
│ ├── live
│ │ ├── 211231.jpg
│ │ ├── 211231_BB.txt
│ │ ├── 448378.jpg
│ │ ├── 448378_BB.txt
│ │ ├── 460830.jpg
│ │ └── 460830_BB.txt
│ └── spoof
│ ├── 035383.jpg
│ ├── 035383_BB.txt
│ ├── 057847.jpg
│ ├── 057847_BB.txt
│ ├── 080343.jpg
│ ├── 080343_BB.txt
├── 10021
│ ├── live
│ │ ├── 013031.jpg
│ │ ├── 013031_BB.txt
│ │ ├── 025895.jpg
│ │ ├── 025895_BB.txt
│ └── spoof
│ ├── 006434.jpg
│ ├── 006434_BB.txt
│ ├── 021470.jpg
│ ├── 021470_BB.txt
│ ├── 027017.jpg
│ ├── 027017_BB.txt
├── 10022
│ ├── live
│ │ ├── 125401.jpg
│ │ ├── 125401_BB.txt
│ │ ├── 196573.jpg
│ │ └── 196573_BB.txt
│ └── spoof
│ ├── 013054.jpg
│ ├── 013054_BB.txt
│ ├── 015386.jpg
│ ├── 015386_BB.txt
│ ├── 016760.jpg
│ ├── 016760_BB.txt
│ ├── 020204.jpg
│ ├── 020204_BB.txt
├── 10023
│ ├── live
│ │ ├── 000240.jpg
│ │ ├── 000240_BB.txt
│ │ ├── 030384.jpg
│ │ ├── 030384_BB.txt
│ │ ├── 034898.jpg
│ │ ├── 034898_BB.txt
│ └── spoof
│ ├── 022241.jpg
│ ├── 022241_BB.txt
│ ├── 023855.jpg
│ ├── 023855_BB.txt
│ ├── 030252.jpg
│ ├── 030252_BB.txt
│ └── 475104_BB.txt
[it goes on, as you guys suggested I put up the real directory rather than a simplified version]
我想 cp 或 mv all*/live/*.jpg
并*/live/*.png
进入另一个目录,dir
如何实现此目的?
我尝试过的事情:
rsync -av ~/train/*/*.jpg dir
find ~train/ -type f -name '*/live/*.jpg' -exec cp '{}' dir ';'
rsync -a --include '*.jpg' --exclude 'live/*' ~/train/ dir
答案1
find -path '/media/data/woreom/dataset/CelebA_Spoof/Data/train /*/real/*.jpg' -type f -exec cp '{}' /media/data/woreom/dataset/dataset/real/ ';'
什么也没做。
/media/data/woreom/datase…
这是因为您要求在当前工作目录中查找。
您需要指定搜索位置作为第一个参数。所以改为(我认为这应该可以。)
find /media/data/woreom/dataset/CelebA_Spoof/Data/train \
-path '/*/real/*.jpg' -type f \
-exec echo cp '{}' /media/data/woreom/dataset/dataset/real/ ';'
我添加了echo
测试这个词,当它工作正常时删除。
答案2
正如我所看到的,在这种情况下,不存在任何名称为 的子目录real
,因此,如果您共享真实的目录名称,则可能您的关键字有一些问题。顺便说一句,您可以使用带有结构 @Kusalananda 的“find”或使用 for 循环来 cp 您的文件和目录
答案3
假设您将其适应您的目录结构并且我正确理解您,这应该可行。
user@user:~$ tree
├── dir
└── foo
├── 10021
│ └── live
│ ├── a.jpg
│ ├── b.jpg
│ ├── c.jpg
│ └── d.jpg
├── 10022
│ └── live
│ ├── e.jpg
│ └── f.jpg
└── 10023
└── live
├── g.jpg
├── h.jpg
├── i.jpg
└── j.jpg
现在,放入您的主目录:
cp */live/*.{jpg,png} ~/dir/
答案4
您可以让 shell 使用通配符来完成繁重的工作
shopt -s nullglob
cp */live/*.jpg */live/*.png dir/
第一个命令告诉bash
shell 不要无法扩展不存在的模式,而是将它们作为不匹配项删除。 (例如,从您的问题来看,目录中没有png
文件10020/live/
;通常这意味着该命令最终会看到10020/live/*.png
无法匹配的文字,因为没有png
名称带有星号的文件。)
如果你不跑bash
你可以重定向标准错误将命令的输出设置cp
为 null ( cp ... 2>/dev/null
),以便您不会看到因扩展模式(例如10020/live/*.png
)无效失败而生成的错误消息,但您也会重定向其他错误消息,因此这应该是最后一步选项。
如果您确实想要一个干净的解决方案,您可以逐个复制文件,但效率较低并且通常难以阅读
for file in */live/*.jpg */live/*.png
do
[ -f "$file" ] && cp "$file" dir/
done
你实际上不需要尾部斜杠dir/
,但我倾向于这样写,以使其清楚地表明我打算dir
成为一个目录。 (在极端情况下,您最终只复制一个dir
不存在的文件,使用dir/
而不是只是dir
会触发错误而安全地失败,而不是默默地将文件重命名为dir
。)
在这两种情况下,您都可以echo
在cp
命令前添加前缀来查看将要执行的命令,而无需实际更改(即使用echo cp …
而不是仅仅cp …
)