10

I have a top folder with many sub-folders. It's named "a". There are many .png and .jpg files in there. I'd like to recursively copy "a" into a new folder "b", but only copy the .png and .jpg files. How do I achieve that?

don_crissti
  • 79,330
  • 30
  • 216
  • 245
JasonGenX
  • 203
  • 1
  • 2
  • 6
  • 4
    `rsync -a --include='*.png' --include='*.jpg' --include='*/' --exclude='*' a/ b/` If you want to prune empty dirs add the `-m` switch : `rsync -am ....` – don_crissti Feb 21 '16 at 20:18
  • 1
    Please specify whether you want to recreate the directory structure (including only the `jpg/png` files) under `b` or you just want to recursively search for `jpg/png` under `a` and copy them to `b` ? – don_crissti Feb 21 '16 at 21:02
  • 2
    If you want to copy the directory tree recursively, this is a duplicate of http://unix.stackexchange.com/questions/2161/rsync-filter-copying-one-pattern-only . If you want to put all the files directly under b, I can't find a duplicate. Which is it? – Gilles 'SO- stop being evil' Feb 21 '16 at 21:50

5 Answers5

8
find a \( -name "*.png" -or -name "*.jpg" \) -exec cp {} b \;
gardenhead
  • 1,997
  • 2
  • 12
  • 12
4

One-liner

cp $(find a -name "*.jpg" -o -name "*.png") b
Marware
  • 486
  • 3
  • 10
1
for file in $(find a -name "*.jpg" -o -name "*.png")
do
  cp ${file} b/${file}
done
Jakuje
  • 20,974
  • 7
  • 51
  • 70
MelBurslan
  • 6,836
  • 2
  • 24
  • 35
0

A bit shorter if there are more file types, using brace expansion

cp -r source_directory/*.{png,jpg,jpeg} target_directory

This gives an error whenever a file of a type does not exist. see https://serverfault.com/a/153893
Add 2>/dev/null to hide these errors
Add || : to not cause an exit code

cp -r source_directory/*.{png,jpg,jpeg} target_directory 2>/dev/null || :
0

You could use bash globstar with cp --parents:

shopt -s globstar
mkdir -p dest
cp --reflink=auto --parents **/*.jpg **/*.png dest/
xiota
  • 526
  • 1
  • 4
  • 13