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
  • 82,805
JasonGenX
  • 203
  • 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
  • 2,017
4

One-liner

cp $(find a -name "*.jpg" -o -name "*.png") b
Marware
  • 486
  • 3
  • 10
2
for file in $(find a -name "*.jpg" -o -name "*.png")
do
  cp ${file} b/${file}
done
Jakuje
  • 21,357
MelBurslan
  • 6,966
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