Cp dir recursively excluding 2 subdirectories

I have 1 directory with 9 subdirectories and 10 files. The subdirectory contains subdirectories and files of the next level.

/home/directory/ /home/directory/subdirectory1 /home/directory/subdirectory2 ... /home/directory/subdirectory9 /home/directory/file1 ... /home/directory/file10 

I want to copy all subdirectories and files, recursively excluding:

 /home/directory/subdirectory5 /home/directory/subdirectory7 

What is the best way to do this?

+8
linux unix bash cp
source share
7 answers

Perhaps the find will help you:

 $ find /home/directory -mindepth 1 -maxdepth 1 -name 'subdirectory[57]' -or -exec cp -r {} /path/to/dir \; 
+8
source share
 rsync -avz --exclude subdirectory5 --exclude subdirectory7 /home/directory/ target-path 
+27
source share

I don't know how to do this with cp , but pretty easy with rsync and --exclude .

+8
source share

using rsync with --exclude better

+2
source share

You can use the --exclude option for tar :

 { cd /home/directory; tar -c --exclude=subdirectory5 --exclude=subdirectory7 .; } | { cd _destination_ ; tar -x; } 
+2
source share

Kev is better, but this will also work:

 find "/home/folder" -maxdepth 1 | sed -e "/^\/home\/folder$/d" -e "/^\/home\/folder\/subfolder5$/d" -e "/^\/home\/folder\/subfolder7$/d" -e "s/^/cp \-r /" -e "s/$/ \/home\/target/" | cat 

Clarification:

 find "/home/folder" -maxdepth 1 | // get all files and dirs under /home/folder, pipe output sed -e "/^\/home\/folder$/d" // have sed strip the path being searched, or the cp -r we prepend later will pickup the excluded dirs again. -e "/^\/home\/folder\/subfolder5$/d" // have sed strip subfolder5 -e "/^\/home\/folder\/subfolder7$/d" // have sed strip subfolder7 -e "s/^/cp \-r /" // have sed prepend "cp -r " to each line -e "s/$/ \/home\/target/" | cat // have sed append targetdir to each line. 

Outputs:

 cp -r /home/folder/subfolder9 /home/target cp -r /home/folder/subfolder1 /home/target cp -r /home/folder/file10 /home/target cp -r /home/folder/subfolder2 /home/target cp -r /home/folder/file1 /home/target cp -r /home/folder/subfolder3 /home/target 

Change | cat | cat on | sh | sh to execute the command.

<A big disclaimer is coming here>

Best Kev Solution

+1
source share

Why not just use the cp command as follows:

 cp -r /home/directory/!(subdirectory5|subdirectory7) /destination 
+1
source share

All Articles