具有特定文件扩展名的 cp 递归

Ins*_*eup 9 command-line bash cp

我正在尝试复制所有.odt文件,包括子目录中的文件。

cp -r ~/Documents/* ~/copies # works as expected
Run Code Online (Sandbox Code Playgroud)
cp -r ~/Documents/*.odt ~/copies # does not work as expected
Run Code Online (Sandbox Code Playgroud)

第一行会复制所有文件和所有子目录中,但第二只复制.odt的文件~/Documents,并没有在子目录中的文件。

ste*_*ver 16

您可以让 (bash) shell 代替执行递归:

shopt -s globstar
cp -nt ~/copies/ ~/Documents/**/*.odt
Run Code Online (Sandbox Code Playgroud)

或使用find命令

find ~/Documents -name '*.odt' -exec cp -nt ~/copies/ {} +
Run Code Online (Sandbox Code Playgroud)

ARG_MAX如果文件数量很大,前者可能会超出系统的限制,而后者会将命令分解为保持在ARG_MAX.

我添加了-n防止“破坏”同名文件的选项。

  • @Insideup 不客气 - 我应该提到上述将每个文件复制到`~/copies` 的顶层。如果你想复制目录结构(更像 `cp -r` 所做的)但只用 `.odt` 文件填充它,这可能最好使用 `rsync` 命令来处理。 (3认同)

sud*_*dus 6

如果你想复制的目录结构(更像是cp -r不会通过steeldriver建议),但只有与填充它.odt的文件,你可以做到这一点rsync,这里-f是“过滤器”选项。其他选项更直接。您可以在 中找到所有选项man rsync

rsync -nvr -f '+ *.odt' -f '+ **/' -f '- *' --prune-empty-dirs ~/Documents/ ~/copies/
Run Code Online (Sandbox Code Playgroud)

最好使用 'dry run' 选项-n和 verbose 选项-v,以便查看在运行实际命令(何时从命令行n中删除)之前将执行的操作。