-1

I would like to copy all (in this case) mp4, jpg, png files which are in different directories. I would do this in macOS terminal.

For instance :

./dir11/dir2/im.png
./dir11/vi.mp4
./dir12/ima.png
./dir12/main.py
./dir12/dir2/infos.txt
./img.jpg

Result : Copy mp4, jpg and png files in found/

./found/im.png
./found/vi.mp4
./found/ima.png
./found/img.jpg
  • https://stackoverflow.com/questions/15617016/copy-all-files-with-a-certain-extension-from-all-subdirectories – chenchuk Nov 03 '18 at 07:31

2 Answers2

1

using rsync

$ find -E . -regex '.*\.(jpg|png|mp4)' -exec rsync -avzh {} ./found/ \;

using cp

$ find -E . -regex '.*\.(jpg|png|mp4)' -exec cp {} ./found/ \;

PS - Not sure which one is more efficient. I usually prefer rsync for the copies & moves.

vivekyad4v
  • 13,321
  • 4
  • 55
  • 63
  • When I test yours commands (rsync et cp ways), I get the "find: illegal option -- t" error :/ – MarcAntony Nov 03 '18 at 07:55
  • It's just a `-` not `--`, not sure why it's formatting like this. `find -type f -regex ".*/.*\.\(mp4\|jpg\|png\)" -exec rsync -avzh {} ~/found/ \;` – vivekyad4v Nov 03 '18 at 08:00
  • With rsync use `-avzh` & cp `-t` . Should work well on most of unix/linux. – vivekyad4v Nov 03 '18 at 08:01
  • ahh.. seems like they are not compatible with MacOS. Updated my answer, tried in MacOS, works fine. Give it a shot. – vivekyad4v Nov 03 '18 at 08:42
  • Your command shows me the right files (thanks for that :D)... but there aren't actually copy in the folder `found` :/ – MarcAntony Nov 03 '18 at 08:46
  • ah.. you wanted to copy it in `./found`, I was copying it in `~/found/`. Updated my answer, try it one last time ;) . – vivekyad4v Nov 03 '18 at 08:49
  • Euh... I understand that `~/found/` is the path, so I already edited this :/ In fact it's `../test/' so it doesn't fix the error :/ – MarcAntony Nov 03 '18 at 08:54
  • Oh... sorry.. I checked in the finder if the files were copied but it actually not refreshing (which it's weird). But the files are actually copied... Thanks you so much :D – MarcAntony Nov 03 '18 at 09:07
  • One last question do you have a way to make your command not case sensitive ? A code which copy ".PNG" and ".png" files ? – MarcAntony Nov 03 '18 at 09:08
  • I don't think we can integrate something out of the box for this solution but you can certainly add more `regex` like `find -E . -regex '.*\.(jpg|png|mp4|JPG|MP4|PNG)'` – vivekyad4v Nov 03 '18 at 09:10
  • Thanks, It will work. Tank you for helped me that way :D – MarcAntony Nov 03 '18 at 09:14
  • Just one last question :| I would like to preserve creation date, like do `cp -p file /dir`. So I tried to add `-p` in your second command (cp way) but it didn't work... Do you have any idea ? – MarcAntony Nov 04 '18 at 10:03
0

You can use find to find a list of different file names, and then pipe it via xargs to cp:

find ./looking -type f \( -name "*.mp4" -or -name "*.jpg" \) | xargs cp -t ./found

This will copy files from the folder ./looking to the folder /found...

edit

Or in your case you probably just want to replace ./looking with ./

updated version for macOS

Since macOS cp does not support -t.

find . -type f ( -iname "*.log" -or -iname "*.jpg" ) | sed 's/ /\\ /g' | xargs -I '{}' cp '{}' ../test-out

Where:

  • The find part looks for all files (not folders) named *.log or *.jpg, and not case sensative (-iname instead of -name)
  • The sed part inserts a "\" before any white spaces in a path
  • The xargs part uses placeholder ({}) to put all the arguments into the cp command.
code_fodder
  • 15,263
  • 17
  • 90
  • 167