How to use 'cp' command to exclude a speci

2019-01-07 01:28发布

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?

标签: linux cp
17条回答
戒情不戒烟
2楼-- · 2019-01-07 01:53

rsync is fast and easy:

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude

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.

查看更多
【Aperson】
3楼-- · 2019-01-07 01:54
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-07 01:55

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:

$ shopt -s extglob
$ echo images/*
images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png
$ echo images/!(*.jpg)
images/004.bmp images/2252.png

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,

% setopt EXTENDED_GLOB
% echo images/*
images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png
% echo images/*~*.jpg
images/004.bmp images/2252.png

So x~y matches pattern x, but excludes pattern y. Once again, for full details refer to manpage.


fishnew!

The fish shell has a much prettier answer to this:

                                                                    
查看更多
狗以群分
5楼-- · 2019-01-07 01:56
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir

Edit: forgot to exclude the target path as well (otherwise it would recursively copy).

查看更多
成全新的幸福
6楼-- · 2019-01-07 01:59

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.

查看更多
霸刀☆藐视天下
7楼-- · 2019-01-07 01:59

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:

  1. The last slash / 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.
  2. The the --exclude path is relative to the source directly. Even if you put full absolute path, it will not work.

  3. -v is for verbose, -a is for archive mode which means you want recursion and want to preserve almost everything.

查看更多
登录 后发表回答