私はディレクトリ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]
*/live/*.jpg
cpまたはmvの両方を実行して*/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
ワイルドカードを使用して、シェルに重い操作を実行させることができます。
shopt -s nullglob
cp */live/*.jpg */live/*.png dir/
最初のコマンドは、bash
存在しないパターン拡張に失敗することなく、不一致で削除するようにシェルに指示します。 (たとえば、あなたの質問によると、ディレクトリにpng
ファイルがありません。これは通常、名前にアスタリスクが付いたファイルがないため、コマンドが10020/live/
一致しないリテラルを表示することを意味します。)10020/live/*.png
png
実行しないとbash
リダイレクトできます。標準エラー誤った拡張モード(例:)エラーによって生成されたエラーメッセージが表示されないように、コマンド出力をcp
null()に設定します。ただし、他のエラーメッセージもリダイレクトされるため、これは最後のステップオプションでなければなりません。cp ... 2>/dev/null
10020/live/*.png
本当にきれいなソリューションが必要な場合は、ファイルを1つずつコピーできますが、これは効率が悪く、読みにくいことがよくあります。
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 …