I have a lot of .CR2 and .ARW files mixed together in a directory structured by date (2016 has the folder 06 and 07 within it with a folder for each day in them. So a file could be located in 2016/06/03 for example).

I want to extract the .ARW files into a separate folder while keeping the structure. Is this possible?

That is, I want to have two 2016 folders with the same structure but in one, there should only be .ARW files and in one there should only be .CR2 files.

  • When you say "extract", you mean "move", right?
    – Kusalananda
    Jul 25 '16 at 19:10
  • You cannot have two directories/files named the same, so you cannot have two 2016 dir
    – tachomi
    Jul 25 '16 at 19:32
  • @tachomi You can have two directories with the same name as long as they aren't in the same directory. I keep tmp/ directories all over the place for stuff that I don't plan to keep long.
    – Centimane
    Jul 25 '16 at 19:40
  • @Dave I'm very agree with that, but the OP is not specifying he needs only for a while that dir and they could be in different directories
    – tachomi
    Jul 25 '16 at 19:51
  • @tachomi It's also a bit ambiguous if the names are 2016 or just contain 2016
    – Centimane
    Jul 25 '16 at 19:56

These rsync commands should do what you're looking for

This will do ARW

rsync -arvz --progress --include='*.ARW' --include="*/" --exclude="*" ./source-dir-2016 ./target-ARW-2016

And this will do CR2

rsync -arvz --progress --include='*.CR2' --include="*/" --exclude="*" ./source-dir-2016 ./target-CR2-2016

I used this post for a source of information.


I'll suggest an alternative using find exec and cp --parents

find ./ -name *.ARW -exec cp --parents {} /home/user/target-ARW-dir/ \;
find ./ -name *.CR2 -exec cp --parents {} /home/user/target-CR2-dir/ \;

The limitation of this is that it your working directory has to just above the file structure you want to copy.

An idea of what it does:

find find files

./ the directory it will look in

-name *.ARW only list files that end in .ARW

-exec perform commands on the list of files returned

cp --parents copy and maintain the directory structure

{} expands to each of the files find reports, think of it like the x in for x in $files

/home/user/target-ARW-dir/ just an example directory, you should change this to what you actually want

\; proper way to terminate a find -exec so that it acts like a for loop


What about cp recursively the 2016 dir to a 2016_ARW and rm *.CR2 from that, then rm *.ARW from the main.


user:~$ ls 2016/06/03/
file_one.ARW file_two.CR2 file_three.CR2 file_four.ARW file_five.ARW
user:~$ cp -R 2016 2016_ARW
user:~$ rm 2016_ARW/06/03/*.CR2
user:~$ rm 2016/06/03/*.ARW
user:~$ ls 2016/06/03/
file_two.CR2 file_three.CR2
user:~$ ls 2016_ARW/06/03/
file_one.ARW file_four.ARW file_five.ARW
  • 1
    The OP suggested that the directory structure is YYYY/MM/DD/file.ARW, so you probably want your rm to be more like rm 2016_ARW/*/*/*.CR2 (wildcards for month, day, and filename)
    – Centimane
    Jul 25 '16 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.