带有带有中间目录变量的模式的 cp 文件

带有带有中间目录变量的模式的 cp 文件

我有一个目录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/

第一个命令告诉bashshell 不要无法扩展不存在的模式,而是将它们作为不匹配项删除。 (例如,从您的问题来看,目录中没有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。)

在这两种情况下,您都可以echocp命令前添加前缀来查看将要执行的命令,而无需实际更改(即使用echo cp …而不是仅仅cp …

相关内容