Linux 递归复制特定文件

Linux 递归复制特定文件,linux,bash,find,cp,Linux,Bash,Find,Cp,这个问题已经被广泛讨论过了,但我找不到一个对我有帮助的解决方案 我试图有选择地将文件从目录树复制到特定文件夹中。在阅读了一些问答之后,以下是我尝试的: cp `find . -name "*.pdf" -type f` ../collect/ 我在正确的父目录中,确实有一个collecta级以上的目录。现在我得到一个错误:cp:invalid选项--“o” 出了什么问题?要处理困难的文件名: find . -name "*.pdf" -type f -exec cp {} ../collect

这个问题已经被广泛讨论过了,但我找不到一个对我有帮助的解决方案

我试图有选择地将文件从目录树复制到特定文件夹中。在阅读了一些问答之后,以下是我尝试的:

cp `find . -name "*.pdf" -type f` ../collect/
我在正确的父目录中,确实有一个
collect
a级以上的目录。现在我得到一个错误:cp:invalid选项--“o”


出了什么问题?

要处理困难的文件名:

find . -name "*.pdf" -type f -exec cp {} ../collect/ \;
默认情况下,
find
将打印找到的文件名。如果使用
-exec
选项,则会将文件名传递给您选择的命令,在这种情况下,会将
cp
命令写入:

cp {} ../collect/ \;
{}
告诉
find
在哪里插入文件名。给
-exec
的命令末尾用分号标记。通常,外壳会吃掉分号。因此,我们用反斜杠转义分号,以便将其作为参数传递给
find
命令

因为
find
直接将文件名提供给
cp
,而不受shell的干扰,所以这种方法甚至适用于最困难的文件名

更有效率 上述操作将对找到的每个文件运行
cp
。如果有很多文件,那么会启动很多进程。如果有GNU工具,可以通过以下方式避免:

find . -name '*.pdf' -type f -exec cp -t ../collect {} +

在此命令变体中,
find
将为每次调用
cp
提供许多文件名,这可能会大大减少需要启动的进程数。

单独运行find命令:是否有一个或多个文件名中有空格?也许像“我的名字-o如果天真地使用.pdf会成为一个问题”?你说得对。文件夹结构中有各种斜杠、空格和括号,因为它们是按日期维护的。有什么解决办法吗?@John1024它只复制那些名称中没有空格的文件。我能做些什么将空格转换成下划线然后重试吗?@dotslash我刚刚发布了一个应该更有效的答案。@John1024,我刚刚接受了它。巨大的“谢谢”从我身边传来!:)工作起来很有魅力!想解释一下它是如何变魔术的吗?:)@他补充道。如果您还有问题,请告诉我。完全可行。请注意,对于找到的每个文件,cp将被调用一次。对于几十个或数百个文件来说,这不是问题,但有时为被调用的程序提供更多的参数,并且调用它的次数要少得多(比如,一万个文件),这是一个胜利。这就是
xargs
可能有用的地方,例如:
find-名称'*.pdf'-type f-print0 | xargs-0 cp-t../collect
@sjnarv好主意!我在答案中添加了一个版本,但没有
xargs
。@John1024真棒的答案!最后一件事:
find
为什么需要分号?我在其他命令行工具/命令中看不到它。