从所有子目录复制具有特定扩展名的所有文件

Abd*_*del 97 unix bash cp

在unix下,我想将所有具有特定扩展名的文件(所有excel文件)从所有子目录复制到另一个目录.我有以下命令:

cp --parents `find -name \*.xls*` /target_directory/
Run Code Online (Sandbox Code Playgroud)

这个命令的问题是:

  • 它也复制了目录结构,我只想要文件(所以所有文件都应该在/ target_directory /中)

  • 它不会复制文件名中包含空格的文件(这些文件很多)

针对这些问题的解决方案?

Bri*_*new 150

--parents 正在复制目录结构,所以你应该摆脱它.

你写的这个问题的方法,在find执行时,其输出被放到命令行,从而cp不能空格分开的文件名和空间区分的文件名.做一些像这样的事情会更好

$ find . -name \*.xls -exec cp {} newDir \;
Run Code Online (Sandbox Code Playgroud)

其中cpfind找到的每个文件名执行,并正确传递文件名.这里有关于这种技术的更多信息.

而不是以上所有,您可以使用zsh并简单地键入

$ cp **/*.xls target_directory
Run Code Online (Sandbox Code Playgroud)

zsh 可以扩展通配符以包含子目录,并使这类事情变得非常容易.

  • `Bash` 4.0+和`ksh93`也支持`**`.对于bash,使用`shopt -s globstar`来启用它.对于ksh,它是`set -G`或`set -o globstar`. (12认同)
  • 那个exec在技术上比传入xargs效率低,而xargs会在尽可能少的cp调用中完成所有操作:`find.-name'*.xls'-print0 | xargs -0 cp -t destdir` (4认同)
  • 是。“ bin it”意味着将其丢弃。现在修改:-) (2认同)
  • @Daryl-我已进一步填写。但请注意,答案已被标记为“已接受” (2认同)
  • @Taywee - 是的。然而,我不想混淆事情,只是专注于特定问题。进一步的效率措施总是好的 (2认同)
  • @BrianAgnew 哦,我敢肯定,在任性的谷歌员工的评论中提供额外信息真是太好了。 (2认同)

guy*_*uya 28

综上所述,我想出了这个版本.这个版本也适用于mac恢复终端.

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'
Run Code Online (Sandbox Code Playgroud)

它将在当前目录中以递归方式查找具有xsl扩展名的文件的所有子目录.它会将它们全部复制到目标目录.

cp标志是:

  • p - 保留文件的属性
  • r - 递归
  • v - 详细(显示你被复制了)

  • 它不是preserver的子目录. (4认同)
  • @MatthewDean您可以使用“cp”的“--parents”标志来实现这一点。像 `find ./ -name '*.xsl' -exec cp --parents {} targetDir/ ';'` (4认同)
  • 有没有办法修改它以保留子目录? (3认同)
  • @ b005t3r是设计使然,不应该这样。这就是《任择议定书》问题的全部意图。他希望将子目录中的所有文件复制到一个没有子目录的目录中 (2认同)

小智 8

我遇到了类似的问题.我解决了它:

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"
Run Code Online (Sandbox Code Playgroud)

'{}'";"执行上的每个文件的副本.


小智 7

到 2022 年,zsh 解决方案也可以在 Linux Bash 中运行:

cp **/*.extension /dest/dir
Run Code Online (Sandbox Code Playgroud)

按预期工作。


小智 6

我也必须自己做这件事。我通过 cp 的 --parents 参数做到了:

find SOURCEPATH -name filename*.txt -exec cp --parents {} DESTPATH \;
Run Code Online (Sandbox Code Playgroud)