-exec 的缺失参数是什么?

我使用以下命令来清空一个目录中超过30天的文件和子目录,并将它们移动到一个存档目录中。如果没有人要求他们的文件,几周后我可以删除这个存档目录。目标目录下有按用户名分的子目录,存档目录也是如此。
我使用的命令如下:
find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

我建议对这个问题在ask ubuntu上提出了一个修改后的版本,另一个用户编辑了代码,将行尾的\;改为+,因为这样更快(而且更正确?)。点击这里查看
然而,如果使用+的话,只有当-exec命令是ls -lh时才有效,而不适用于我实际使用的命令。如果我尝试使用+,会收到错误消息:
find: missing argument to '-exec'

我不明白为什么它会这样行为,或者正确的命令应该是什么。请不要只给出修正的指令,我希望能够理解而不是盲目地遵循建议。

你是在指的这个回答吗?这个可能会解释为什么。 - Wilf
谢谢@Wilf,我已经更新了以显示编辑发生的答案。你提供的链接还有一个进一步的链接,以一种我大脑能够理解的方式来解释。 - Arronical
感谢@souravc以一种巧妙的循环方式,这个问题是由编辑我的命令的用户提出的!最后我明白了+可以为同一个命令提供多个参数,但是mv无法处理这种情况! - Arronical
@Arronical mv可以,看我的回答^^ - chaos
2个回答

那篇帖子中的用户可能说过,在-exec命令的末尾加上+符号会更快,但没有解释为什么。
假设find命令返回以下文件:
/path/to/file1
/path/to/file2
/path/to/file3

正常的-exec命令(-exec command {} \;)对每个匹配的文件运行一次。例如:
find ... -exec mv {} /target/ \;

执行:
mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

如果你使用+符号(-exec command {} +),命令会在末尾添加多个匹配的文件。例如:
find ... -exec mv -t /target/ {} +

执行:
mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

要正确使用+标志,进程的参数必须位于命令的末尾,而不是中间。这就是为什么在你的例子中,find会抛出missing argument to '-exec'的原因;它缺少了闭合的{}

我一直很好奇为什么在使用find -exec+结合时,{}必须是最后一个参数。有人知道为什么做出了这个设计决定,而不是让像OP的命令行这样的结构起作用吗? - Peter Cordes

用户解释了他们的编辑内容...

'+' exec's terminator is faster than '\;' see https://askubuntu.com/questions/558817/what-is-the-difference-between-using-and-in-exec-command; and creating a backup file from original file is good idea

...使用此链接。我认为基本上不再使用多个命令,而是将所有文件名发送到一个命令实例中以加快速度。这里是一个来自这里的示例:

Using -exec with a semicolon (find . -exec ls '{}' \;), will execute

ls file1
ls file2
ls file3

But if you use a plus sign instead (find . -exec ls '{}' \+), all filenames will be passed as arguments to a single command:

ls file1 file2 file3
还有其他可用的形式,使用;+(从这里:)

因此,对于find命令,允许以下示例语法:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +
然而,我不确定这个移动命令是否适用,因为它的语法是mv [OPTION]... SOURCE DEST,除非使用-t选项或类似选项。但是,对于ls而言,应该可以正常工作,无需额外的选项等,因为它们可以理解给定多个文件名时的情况。可能还需要对+进行转义(即\+)。

两个都很好的回答,但我得给混沌点赞,因为他稍微快一点,并且解释了mv -t,不过两个回答都值得加一分! - Arronical