如何使用'命令排除指定目录?

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

621847 次浏览
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir

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

为什么使用rsync当你可以做到:

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

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

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

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

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

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

好吧,如果每个unix文件实用程序(如cp、mv、rm、tar、rsync、scp等)都必须排除某些文件名模式,那么就会发生大量的重复工作。相反,这些事情可以作为globbing的一部分来完成,即通过shell来完成。

bash

# eyz1, # eyz2 # eyz3。

例子:

$ 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

# eyz1, # eyz2 # eyz3。

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

% 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。再次强调,详细信息请参阅manpage。


鱼# EYZ0 > < /晚餐

shell有一个更漂亮的答案到这个:

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

奖金pro-tip

输入cp *,点击CtrlX,看看会发生什么。# EYZ4 > < /晚餐

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

扩展mvds的评论,这对我来说是可行的

cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
cp -r `ls -A | grep -v "c"` $HOME/

rsync是快速和简单的:

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

您可以多次使用--exclude

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

注意,在--exclude选项之后的dir thefoldertoexclude是相对于sourcefolder的,即sourcefolder/thefoldertoexclude

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

rsync

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

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

只需将其临时移动到一个隐藏目录中(如果需要的话,可以重新命名它)。

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

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

这个命令对我很管用:

# EYZ0

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

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

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

我用“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上的文件更新的所有音乐类型文件。我使用上面的方法是因为我有很多DVD文件,mpeg等,我想排除,因为某种原因rsync看起来像是在复制,但在我看了wd设备后,文件不存在,尽管在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/

rsync实际上相当棘手。要做多次测试才能起作用

假设您想要复制/var/www/html/var/www/dev,但可能由于其大小需要排除 /var/www/html/site/video/目录。命令如下:

# EYZ0

一些# EYZ0:

  1. 源文件中的最后一个斜杠/是必需的,否则它也会复制源目录而不是其内容,并变成/var/www/dev/html/xxxx,这可能不是您想要的。
  2. --exclude路径是相对于源的 。即使你使用完全的绝对路径,它也不会起作用。

  3. -v是verbose, -a是存档模式,这意味着你想要递归,并想要保存几乎所有内容。

它相对于源目录。< br > 这将排除复制目录source/.git。< / p >

rsync -r --exclude '.git' source target
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir

第一部分ls所有文件,但隐藏的特定文件与标志-Ils的输出被用作第二部分的标准输入。从标准输入构建并执行命令cp -rf -t destdir。标记-r表示递归复制目录,-f表示强制复制文件,这将覆盖destdir中的文件,-t指定复制到的目标目录。

cp -r `ls -A | grep -v "Excluded_File_or_folder"` ../$target_location -v

晚了10年。感谢Linus Kleen。

我讨厌rsync!,)所以为什么不使用findcp呢?用这个答案还mkdir创建一个不存在的文件夹结构。

# EYZ0

# EYZ0

它看起来像cd ìs必须连接相对路径与find

mkdir -p将创建所有子文件夹,当文件夹已经存在时不会报错。


侯斯顿,我们还有下一个问题。如果有人创建了一个新文件夹,中间有一个新文件,会发生什么情况?正确:对于这些新文件,它将失败。(解决方案:再运行一次!把所有东西都放在一个find命令中的解决方案似乎很困难。


清理:https://unix.stackexchange.com/q/627218/239596

rsync对我们来说不可用。下面是一个可行的替代方案。

tar -cf - --exclude='./folder' --exclude='./file.tar' ./source_directory | tar -xf - -C ./destination_directory