Linux:将所有与模式匹配的文件从dir和subdirs复制到单个dir


31

如果要复制所有*.so文件到srcdst请执行以下操作:

cp src/*.so dst

但是,我想将*.sosrc及其子目录中的所有文件复制到中dst。有什么线索吗?

Answers:


36

尝试:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

17
find可以进行模式匹配并执行命令。有没有必要管其输出:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
jáquer

1
是的,它可以,但是通常更容易读取管道,而且模式匹配功能grep远远超过了-name参数to中使用的简单外壳模式findxargs还比的-exec参数强大find
Mike Insch

2
@jaquer的解决方案要好得多,因为在MacOSX上,xargs实用程序没有-i选项。但是他的解决方案就像一个魅力。
bialix

在阅读xbias的-i参数的错误消息之前,我一直在挣扎,直到我阅读了来自@bialix的有关jaquer解决方案的评论,该评论在我的Mac上非常有效。谢谢
svannoy

是否会根据需要创建子目录?
Lennart Rolland

15

如果您使用的是Bash,则可以打开globstar shell选项以递归方式匹配文件和目录:

shopt -s globstar
cp src/**/*.so dst

如果您需要查找名称以开头的文件.和/或名称以开头的目录中和目录下的文件,请同时.设置dotglob选项(例如使用shopt -s dotglob)。您可以在一个命令中同时设置它们:

shopt -s globstar dotglob

不会在以开头的子目录中复制文件。以他们的名字
rboy

8

我尝试了Mike建议的命令:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

但最终将所有文件转储到目录中dst,而它们的相对路径也丢失了。

为了保持相对路径,需要将此命令修改为:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}

7
+1。但是,这假定与相对源路径相对应的目录位于下dst。如果不是这样,请使用cp --parents。另外,请务必引用文件名。因此:(... | xargs -i cp --parents "{}" dst请注意,到的最后一个参数cp现在“仅”是目标目录)。使用-t标志:可以使命令更短(并且可能更快)... | xargs cp --parents -t dst
Stephan202 2013年

1
@ Stephan202我必须使用... | xargs cp {} --parents -t dst.
warvariuc

在Mac --parents上无法使用。我用ditto它代替了它:stackoverflow.com/questions/11246070/cp-parents-option-on-mac
Bryan Young

3

这样做的另一种方式是这样的:

find src/ -type f -name "*.so" -exec cp {} dst/ \;

这应该减少数量的cp过程:... -exec cp -t dst/ {} +
卡米尔Maciorowski

嗨,卡米尔!谢谢你的意见!您能给我解释一下您的解决方案如何使事情变得更快!总是愿意了解更多:)
Kyriakos

当以结束-exec;,一次{}替换为一条路径。cp每个文件都有一个单独的名称。使用+语法find替换{}多个结果(最多由系统定义的命令行长度限制;限制:{}必须是之前的最后一件事+,因此cp -t)。创建和终止过程是相对昂贵的事情。因此,+每当您期望获得许多结果时,最好使用它。在这种情况下,复制大量文件可能会花费大量时间,因此差异可能会被忽略。不过,这是个好习惯。
卡米尔Maciorowski

1

可以使用find的-name替换grep :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.