将所有匹配模式的文件从 dir 和 subdirs 复制到单个目录中

Alb*_*ore 43 linux bash

如果我想将所有*.so文件复制srcdst我会这样做:

cp src/*.so dst
Run Code Online (Sandbox Code Playgroud)

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

Mik*_*sch 48

尝试:

find src/ -type f | grep -i so$ | xargs -i cp {} dst
Run Code Online (Sandbox Code Playgroud)

  • `find` 可以进行模式匹配和执行命令。无需管道输出:`find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'` (21认同)
  • @jaquer 的解决方案要好得多,因为在 MacOSX 上 xargs 实用程序没有 -i 选项。但他的解决方案就像一个魅力。 (2认同)

jáq*_*uer 19

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

shopt -s globstar
cp src/**/*.so dst
Run Code Online (Sandbox Code Playgroud)

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

shopt -s globstar dotglob
Run Code Online (Sandbox Code Playgroud)


小智 11

我尝试了 Mike 建议的命令:

find src/ -type f | grep -i so$ | xargs -i cp {} dst
Run Code Online (Sandbox Code Playgroud)

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

要保留相对路径,需要将命令修改为:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}
Run Code Online (Sandbox Code Playgroud)

  • +1。但是,这假设与相对源路径对应的目录存在于 `dst` 下。如果不是这样,请使用`cp --parents`。另外,一定要引用文件名。因此:`... | xargs -i cp --parents "{}" dst`(注意 `cp` 的最后一个参数现在“只是”目标目录)。使用 `-t` 标志可以使命令更短(可能更快): `... | xargs cp --parents -t dst`。 (8认同)

小智 6

另一种方法是这样的:

find src/ -type f -name "*.so" -exec cp {} dst/ \;
Run Code Online (Sandbox Code Playgroud)

  • 当您以“;”结束“-exec”时,“{}”一次会被一个路径替换。每个文件都会有一个单独的“cp”。使用 `+` 语法,`find` 将 `{}` 替换为多个结果(最多达到系统定义的命令行长度限制;限制:`{}` 必须是 `+` 之前的最后一个,因此 `cp -t `)。创建和终止进程是相对昂贵的事情。因此,当您期望得到大量结果时,最好使用“+”。在这种情况下,复制大量文件可能会花费大量时间,因此差异可能会被忽视;尽管如此,这是一个很好的做法。 (3认同)