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?

3
  • 4
    rsync -a --include='*.png' --include='*.jpg' --include='*/' --exclude='*' a/ b/ If you want to prune empty dirs add the -m switch : rsync -am .... Feb 21, 2016 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 ? Feb 21, 2016 at 21:02
  • 2
    If you want to copy the directory tree recursively, this is a duplicate of unix.stackexchange.com/questions/2161/… . If you want to put all the files directly under b, I can't find a duplicate. Which is it? Feb 21, 2016 at 21:50

5 Answers 5

8
find a \( -name "*.png" -or -name "*.jpg" \) -exec cp {} b \;
4
  • Whoops, I accidentally used *.png twice and forgot .jpg. This is what happens when I try to answer questions while listening to music. Thanks for catching my mistake.
    – gardenhead
    Feb 21, 2016 at 20:56
  • OK, I think I got it this time. I learned something new about find today. Thanks.
    – gardenhead
    Feb 21, 2016 at 21:06
  • One more thing: stick with -o instead of -or, it's more portable. Feb 21, 2016 at 21:13
  • This is an excellent answer! Oct 3, 2019 at 13:47
4

One-liner

cp $(find a -name "*.jpg" -o -name "*.png") b
2
for file in $(find a -name "*.jpg" -o -name "*.png")
do
  cp ${file} b/${file}
done
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/

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .