Ubuntu – How to copy a directory without copying a specific file or subdirectory in terminal

command linecpgnome-terminal

I have a directory main_dir which contains lots of files and 3 subdirectories (dir1 and dir2 and dir3). I want to copy it to another location without copying dir2 in one command. I searched the cp manual to see if this can be done somehow but I did not find the answer.
My only solution was to copy the whole directory and then delete dir2 in the copied location.

cp -r main_dir ~/Documents/main_dir_copy
cd ~/Documents/main_dir_copy
rm -r dir2

Is there a way to do this without having to copy all the contents of dir2 and then delete it?

Best Answer

In bash, you can use an extended glob to implement negation.

Given

$ tree main_dir
main_dir
├── dir1
│   ├── other file
│   └── somefile
├── dir2
│   ├── other file
│   └── somefile
├── dir3
│   ├── other file
│   └── somefile
└── file

3 directories, 7 files

then

shopt -s extglob
cp -r main_dir/!(dir2) main_dir_copy/

resulting in

$ tree main_dir_copy
main_dir_copy
├── dir1
│   ├── other file
│   └── somefile
├── dir3
│   ├── other file
│   └── somefile
└── file

2 directories, 5 files

Note that since this recursively copies the contents of main_dir (excluding the given dir2) rather than main_dir itself, the target directory main_dir_copy must already exist - if it doesn't, add mkdir main_dir_copy to the command sequence.

See also