Recursive copy of a specific file type maintaining the file structure in Unix/Linux?

LinuxBashShellRsyncCp

Linux Problem Overview


I need to copy all *.jar files from a directory maintaining the folder structure of the parent directories. How can I do it in UNIX/Linux terminal?
The command cp -r *.jar /destination_dir is not what I am looking for.

Linux Solutions


Solution 1 - Linux

rsync is useful for local file copying as well as between machines. This will do what you want:

rsync -avm --include='*.jar' -f 'hide,! */' . /destination_dir

The entire directory structure from . is copied to /destination_dir, but only the .jar files are copied. The -a ensures all permissions and times on files are unchanged. The -m will omit empty directories. -v is for verbose output.

For a dry run add a -n, it will tell you what it would do but not actually copy anything.

Solution 2 - Linux

If you don't need the directory structure only the jar files, you can use:

shopt -s globstar
cp **/*.jar destination_dir

If you want the directory structure you can check cp's --parents option.

Solution 3 - Linux

If your find has an -exec switch, and cp an -t option:

find . -name "*.jar" -exec cp -t /destination_dir {} +

If you find doesn't provide the "+" for parallel invocation, you can use ";" but then you can omit the -t:

find . -name "*.jar" -exec cp {} /destination_dir ";"

Solution 4 - Linux

cp --parents `find -name \*.jar` destination/

from man cp:

--parents
       use full source file name under DIRECTORY

Solution 5 - Linux

tar -cf - `find . -name "*.jar" -print` | ( cd /destination_dir && tar xBf - )

Solution 6 - Linux

If you want to maintain the same directory hierarchy under the destination, you could use

(cd SOURCE && find . -type f -name *.jar -exec tar cf - {} +) 

| (cd DESTINATION && tar xf -)

This way of doing it, instead of expanding the output of find within back-ticks, has the advantage of being able to handle any number of files.

Solution 7 - Linux

find . -name \*.jar | xargs cp -t /destination_dir

Assuming your jar filenames do not contain spaces, and your cp has the "-t" option. If cp can't do "-t"

find . -name \*.jar | xargs -I FILE cp FILE /destination_dir

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYury PogrebnyakView Question on Stackoverflow
Solution 1 - LinuxSeanView Answer on Stackoverflow
Solution 2 - LinuxuzsoltView Answer on Stackoverflow
Solution 3 - Linuxuser unknownView Answer on Stackoverflow
Solution 4 - LinuxBartosz MoczulskiView Answer on Stackoverflow
Solution 5 - LinuxPavan ManjunathView Answer on Stackoverflow
Solution 6 - LinuxIdelicView Answer on Stackoverflow
Solution 7 - Linuxglenn jackmanView Answer on Stackoverflow