如何使用“cp”命令排除特定的目录?

我想复制一个目录中除一些特定的子目录中的文件的所有文件。 我注意到'cp'命令没有–exclude选项。 那么,我怎么能做到这一点呢?

rsync是快速和容易的:

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

那么,如果每个unix-ish文件实用程序(如cp,mv,rm,tar,rsync,scp,…)都必须执行某些文件名模式的排除,则会发生巨大的重复工作。 相反,这样的事情可以作为globbing的一部分,即通过你的shell。

庆典

链接到手动,searchextglob

例:

 $ shop -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

所以你只是把一个模式放在!() ,否定了匹配。 这个模式可以是任意复杂的,从个别path的枚举开始(如Vanwaril在另一个答案中所示): !(filename1|path2|etc3) ,类似于正则expression式和星星和angular色类的东西。 有关详细信息,请参阅联机帮助页。

zsh的

链接到手册, “文件名生成”部分

你可以做setopt KSH_GLOB并使用类似bash的模式。 要么,

 %setopt EXTENDED_GLOB
 %回显图像/ *
 images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png
 %回显图像/ *〜* .jpg
 images / 004.bmp images / 2252.png

所以x~y匹配模式x ,但不包括模式y 。 有关详细信息,请再次参阅联机帮助页。


奖金提示

键入cp * ,点击Ctrl X * ,看看会发生什么。 我承诺这不是有害的

为什么使用rsync时候可以这样做:

 find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';' 

这假定目标目录结构与来源相同。

 cp -r `ls -A | grep -v "c"` $HOME/ 

我发现的最简单的方法,就是只要在圆括号中添加它们的名字就可以复制除文件和文件夹以外的所有文件:

 cp -r !(Filename1 | FoldernameX | Filename2) Dest/ 

我假设你使用bash或破折号。 这会工作吗?

 shopt -s extglob # sets extended pattern matching options in the bash shell cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination 

做一个ls排除你不想要的文件,并用它作为cp的第一个参数

扩大mvds的评论 ,这对我有用

 cd dotfiles tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2 

另一个更简单的select是安装和使用具有–exclude-dir选项的rsync,并可用于本地和远程文件。

rsync的

 rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/ 

首先用-n选项试试看看会被复制到什么地方

这是对Linus Kleen答案的修改。 他的回答对我不起作用,因为会有一个。 添加在cp不喜欢的文件path前(path看起来像source / .destination / file)。

这个命令为我工作:

find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;

–parents命令保留目录结构。

 mv tobecopied/tobeexcluded . cp -r tobecopied dest/ mv tobeexcluded tobecopied/ 

只要把它暂时移动到一个隐藏的目录中(如果需要,可以重命名它)。

 mkdir .hiddendir cp * .hiddendir -R mv .hiddendir realdirname 

一种方法是使用find -0-prune来查找所有要移动的文件和目录,然后使用xargs -0来复制每个文件和目录。

 cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir 

编辑:忘记排除目标path(否则它会recursion复制)。

我使用“do while”循环来读取find命令的输出。 在这个例子中,我匹配(而不是排除)某些模式,因为我想要的模式匹配数量比我不想要的要多。 你可以用-iname标志前面的-not来反转逻辑:

  find . -type f -iname "*.flac" -o -print0 -iname "*.mp3" -print0 -o -iname "*.wav" -print0 -o -iname "*.aac" -print0 -o -iname "*.wma" -print0 | while read -d $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done 

我使用上面的方法复制了我的服务器上比我在/ media / wd上安装的Western Digital TV Live Hub上的文件更新的所有音乐types文件。 我使用上面的,因为我有很多的DVD文件,MPEG等,我想排除,因为由于某种原因,rsync看起来像它正在复制,但是在我看了wd设备后,文件不存在,尽pipe没有使用此命令在rsync期间出错:

  rsync -av --progress --exclude=*.VOB --exclude=*.avi --exclude=*.mkv --exclude=*.ts --exclude=*.mpg --exclude=*.iso --exclude=*ar --exclude=*.vob --exclude=*.BUP --exclude=*.cdi --exclude=*.ISO --exclude=*.shn --exclude=*.MPG --exclude=*.AVI --exclude=*.DAT --exclude=*.img --exclude=*.nrg --exclude=*.cdr --exclude=*.bin --exclude=*.MOV --exclude=*.goutputs* --exclude=*.flv --exclude=*.mov --exclude=*.m2ts --exclude=*.cdg --exclude=*.IFO --exclude=*.asf --exclude=*.ite /media/2TB\ Data/data/music/* /media/wd/network_sync/music/