关于linux:如何使用’cp’命令排除特定目录?

How to use 'cp' command to exclude a specific directory?

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


rsync快速简单:

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

您可以使用--exclude倍数。

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

注意,--exclude选项后的dir thefoldertoexcludesourcefolder相对,即sourcefolder/thefoldertoexclude

此外,您还可以添加-n进行干运行,以查看在执行实际操作之前将复制什么,如果一切正常,则从命令行中删除-n


好吧,如果每个unix-ish文件实用程序(如cp、mv、rm、tar、rsync、scp等)都必须执行某些文件名模式的排除,就会出现大量的重复工作。相反,这些事情可以作为环球旅行的一部分,也就是说,通过你的外壳。

猛击

链接到手册,搜索extglob。

例子:

1
2
3
4
5
$ 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

所以你只要在!()中放入一个模式,它就否定了匹配。模式可以是任意复杂的,从单个路径的枚举开始(如vanwaril在另一个答案中所示):!(filename1|path2|etc3),到像regex一样的带有星和字符类的东西。有关详细信息,请参阅手册页。

ZSH

链接到手册的"文件名生成"部分。

您可以执行setopt KSH_GLOB并使用类似bash的模式。或者,

1
2
3
4
5
% 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

因此,x~y与模式x匹配,但不包括模式y。再次,有关详细信息,请参阅手册页。

鱼腥!

鱼壳有一个更漂亮的答案:

1
?? cp (string match -v '*.excluded.names' -- srcdir/*) destdir

奖金奖励小费

键入cp *,点击ctrlx*,然后看看会发生什么。我保证这不会有害


如果可以,为什么要使用rsync

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

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


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


我找到的最简单的方法是,只需在括号中添加文件和文件夹的名称,就可以复制所有文件(不包括文件和文件夹):

1
2
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/


扩展MVD的评论,这对我很有用。

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


远程同步

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

首先用-n选项尝试,看看要复制什么


我猜你用的是bash或dash。这行吗?

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

执行ls排除不需要的文件,并将其用作cp的第一个参数


它是相对于的源目录。这将被排除从copied source/.git目录。

1
rsync -r --exclude '.git' source target

另一个更简单的选项是安装和使用rsync,它有--excludedir选项,可以用于本地和远程文件。


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

这个命令对我有效:

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

--parents命令保留目录结构。


只是暂时移动到一个隐藏的目录中(如果需要的话,可以在后面重命名)。

1
2
3
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname


1
2
3
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/

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

1
    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上的文件更新的所有音乐类型文件。我使用上面的内容是因为我有很多要排除的DVD文件、MPEG等,并且由于某些原因,rsync看起来像是在复制,但是在我查看wd设备之后,尽管在使用此命令进行rsync期间没有错误,但这些文件仍然不存在:

1
    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/

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


rsync是真的很棘手。要使它工作的多个测试。

让我们说你想复制到/var/www/dev/var/www/html但需要排除其可能导致的/var/www/html/site/video/目录的大小。该命令将是:

rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev

一些警告:

  • 最后,在湿地/来源是需要的,否则它也将复制源目录的内容,而不是它的/var/www/dev/html/xxxx起,这也许不是你想要的。
  • --exclude直接路径是相对于光源。即使你把完整的绝对路径,它将无法工作。

  • -v-a是冗长的,这是你想要的任何方式进行归档和保存几乎所有的想。


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

    编辑:也忘记排除目标路径(否则它将递归复制)。


    1
    ls -I"filename1" -I"filename2" | xargs cp -rf -t destdir

    第一部分ls所有文件,但隐藏的文件和-I特异性标志。输出(输入的是ls是用标准的第二部分。编译和运行cp -rf -t destdirxargs命令从标准输入。该标志-r均值复制拷贝文件的目录recursively -f均值,这将覆盖在forcibly文件中指定的目的地destdir-t复制到目录。