I want to copy all files in a directory except some files in a specific sub-directory. I have noticed that 'cp' command didn't have a --exclude option. So, how can I achieve this?
相关问题
- Is shmid returned by shmget() unique across proces
- how to get running process information in java?
- Error building gcc 4.8.3 from source: libstdc++.so
- Why should we check WIFEXITED after wait in order
- Null-terminated string, opening file for reading
rsync is fast and easy:
You can use
--exclude
multiples times.Also you can add
-n
for dry run to see what will be copied before performing real operation, and if everything is ok, remove-n
from command line.Well, if exclusion of certain filename patterns had to be performed by every unix-ish file utility (like cp, mv, rm, tar, rsync, scp, ...), an immense duplication of effort would occur. Instead, such things can be done as part of globbing, i.e. by your shell.
bash
Link to manual, search for extglob.
Example:
So you just put a pattern inside
!()
, and it negates the match. The pattern can be arbitrarily complex, starting from enumeration of individual paths (as Vanwaril shows in another answer):!(filename1|path2|etc3)
, to regex-like things with stars and character classes. Refer to the manpage for details.zsh
Link to manual, section "filename generation".
You can do
setopt KSH_GLOB
and use bash-like patterns. Or,So
x~y
matches patternx
, but excludes patterny
. Once again, for full details refer to manpage.fishnew!
The fish shell has a much prettier answer to this:
Edit: forgot to exclude the target path as well (otherwise it would recursively copy).
Another simpler option is to install and use rsync which has an --exclude-dir option, and can be used for both local and remote files.
rsync
is actually quite tricky. have to do multiple tests to make it work.Let's say you want to copy
/var/www/html
to/var/www/dev
but need to exclude/var/www/html/site/video/
directory maybe due to its size. The command would be:rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Some caveat:
/
in the source is needed, otherwise it will also copy the source directory rather than its content and becomes/var/www/dev/html/xxxx
, which maybe is not what you want.The the
--exclude
path is relative to the source directly. Even if you put full absolute path, it will not work.-v
is for verbose,-a
is for archive mode which means you want recursion and want to preserve almost everything.