我想复制目录中的所有文件,但特定子目录中的某些文件除外。 我注意到'cp'命令没有--exclude选项。 那么,我怎样才能做到这一点?
答案 0 :(得分:580)
rsync快速简便:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
您可以使用--exclude
倍数。
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
请注意,thefoldertoexclude
选项后的目录--exclude
与sourcefolder
相关,即sourcefolder/thefoldertoexclude
。
此外,您可以为干运行添加-n
以查看在执行实际操作之前将要复制的内容,如果一切正常,请从命令行中删除-n
。
答案 1 :(得分:74)
好吧,如果必须由每个unix-ish文件实用程序(如cp,mv,rm,tar,rsync,scp,...)执行某些文件名模式的排除,则会发生巨大的重复工作。相反,这些事情可以作为globbing的一部分完成,即由你的shell完成。
Link手动搜索 \ textglob 。
示例:
$ 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)
,与星形和字符类的正则表达式一样。有关详细信息,请参阅联机帮助页。
Link到手册,“文件名生成”。
您可以执行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
。有关详细信息,请参阅联机帮助页。
fish shell对此有一个much prettier answer:
cp (string match -v '*.excluded.names' -- srcdir/*) destdir
键入cp *
,按 Ctrl X * ,看看会发生什么。 这是无害的我保证
答案 2 :(得分:42)
为什么在可以的时候使用rsync
:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
这假设目标目录结构与源的结构相同。
答案 3 :(得分:31)
cp -r `ls -A | grep -v "c"` $HOME/
答案 4 :(得分:21)
我找到的最简单的方法,只需在括号中添加名称,即可复制除文件和文件夹之外的所有文件:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
答案 5 :(得分:10)
扩展mvds’s comment,这对我有用
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
答案 6 :(得分:7)
我假设您正在使用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的第一个参数
答案 7 :(得分:7)
rsync的
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
首先尝试使用-n选项查看要复制的内容
答案 8 :(得分:6)
另一个更简单的选择是安装和使用具有--exclude-dir选项的rsync,并且可以用于本地和远程文件。
答案 9 :(得分:3)
这是对Linus Kleen的回答的修改。他的回答对我不起作用,因为会有一个。添加到cp不喜欢的文件路径前面(路径看起来像source / .destination / file)。
这个命令对我有用:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
--parents命令保留目录结构。
答案 10 :(得分:2)
rsync
实际上非常棘手。必须做多个测试才能使它工作。
假设您要将/var/www/html
复制到/var/www/dev
,但可能由于其大小而需要排除 /var/www/html/site/video/
目录。命令是:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
一些警告:
/
,否则它也会复制源目录而不是其内容,并变为/var/www/dev/html/xxxx
,这可能不是您想要的。 直接--exclude
路径相对到源。即使你把完整的绝对路径,它也行不通。
-v
用于详细,-a
用于存档模式,这意味着您需要递归,并希望保留几乎所有内容。
答案 11 :(得分:2)
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
答案 12 :(得分:2)
暂时将其移动到隐藏目录中(如果需要,可将其重命名)。
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
答案 13 :(得分:1)
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
编辑:忘记排除目标路径(否则会递归复制)。
答案 14 :(得分:1)
我使用" 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文件,mpegs等,我想要排除和因为某些原因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/
答案 15 :(得分:1)
一种方法是使用find -0
和-prune
来查找要移动的所有文件和目录,然后使用xargs -0
复制每个文件和目录。
答案 16 :(得分:0)
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir
第一部分ls
所有文件,但带有标志-I
的隐藏特定文件。 ls
的输出用作第二部分的标准输入。 xargs
从标准输入生成并执行命令cp -rf -t destdir
。标志-r
表示递归复制目录,-f
表示强制复制文件,它将覆盖destdir
中的文件,-t
指定目标目录的复制目标。
答案 17 :(得分:0)
cp -r ls -A | grep -v "Excluded_File_or_folder"
../$target_location -v
答案 18 :(得分:0)
晚了十年。感谢 Linus Kleen。
我讨厌rsync
! ;) 那么为什么不使用 find
和 cp
?并通过此答案 mkdir
创建一个不存在的文件夹结构。
cd /source_folder/ && find . -type d -not -path '*/not-from-here/*' -print -exec mkdir -p '/destination_folder/{}' \;
cd /source_folder/ && find . -type f -not -path '*/not-from-here/*' -print -exec cp -au '{}' '/destination_folder/{}' \;
看起来 cd
ì 需要用 find
连接相对路径。
mkdir -p
将创建所有子文件夹,并且在文件夹已存在时不会报错。
我们有下一个问题。当有人创建一个中间有新文件的新文件夹时会发生什么?确切地说:这些新文件将失败。 (解决方案:再次运行它!:))将所有内容放入一个 find
命令的解决方案似乎很困难。