10

I have 1 directory with 9 subdirectories and 10 files. Subdirectory have next level subdirectories and files.

/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 recursivly excluding:

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

What is the best way for it?

tchrist
  • 78,834
  • 30
  • 123
  • 180
dr0zd
  • 1,368
  • 4
  • 18
  • 28
  • first copy complete folder recursively,then use rm command to remove subfolders 5 & 7 – Pradeep Feb 27 '12 at 12:39
  • possible duplicate of [Copy folder recursively, excluding some folders](http://stackoverflow.com/questions/2193584/copy-folder-recursively-excluding-some-folders) – Oleg Estekhin Jun 27 '14 at 08:06

7 Answers7

30
rsync -avz --exclude subdirectory5 --exclude subdirectory7 /home/directory/ target-path
kjohri
  • 1,166
  • 11
  • 10
11

I don't know a good way of doing it with cp, but it's fairly easy using rsync and the --exclude switch.

aioobe
  • 413,195
  • 112
  • 811
  • 826
8

Maybe the find command will help you:

$ find /home/directory -mindepth 1 -maxdepth 1 -name 'subdirectory[57]' -or -exec cp -r {} /path/to/dir \;
tchrist
  • 78,834
  • 30
  • 123
  • 180
kev
  • 155,172
  • 47
  • 273
  • 272
2

use rsync with --exclude is better

Qian
  • 1,007
  • 7
  • 6
2

You can use the --exclude option of tar:

{ cd /home/directory; tar -c --exclude=subdirectory5 --exclude=subdirectory7 .; } | { cd _destination_ ; tar -x; }
jfg956
  • 16,077
  • 4
  • 26
  • 34
1

Why not just use the cp command like this:

cp -r /home/directory/!(subdirectory5|subdirectory7) /destination
Sumit Singh
  • 15,743
  • 6
  • 59
  • 89
1

Kev's way is better, but this would 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

Explained :

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 to | sh to execute the command.

<A big disclaimer goes here>

You should Kev's solution is better

jon
  • 5,986
  • 5
  • 28
  • 35
  • +1 for overcomplicated sed piped to cat or sh- best way to build other complex scripts. +1 for Kev's right answer in this case :) – David Souther Feb 27 '12 at 13:31