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?
Asked
Active
Viewed 1.5k times
10
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
-
1Please 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
-
2If 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 Answers
8
find a \( -name "*.png" -or -name "*.jpg" \) -exec cp {} b \;
gardenhead
- 1,997
- 2
- 12
- 12
-
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 '16 at 20:56
-
OK, I think I got it this time. I learned something new about `find` today. Thanks. – gardenhead Feb 21 '16 at 21:06
-
One more thing: stick with `-o` instead of `-or`, it's more portable. – don_crissti Feb 21 '16 at 21:13
-
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