-exec 缺少的参数是什么?

Arr*_*cal 15 command-line bash find syntax

我使用以下命令清除一个目录,其中包含超过 30 天的文件和目录,并将它们移动到一个存档目录,如果没有人要求取回他们的文件,我可以在几周后将其删除。目标目录有用户名的子目录,归档目录也有。

这是我使用的命令:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;
Run Code Online (Sandbox Code Playgroud)

我建议修改此版本来回答有关 ask ubuntu 的问题,另一个用户编辑了代码以更改行尾\;+因为它更快(并且更正确?)。看这里

但是,+如果该-exec命令ls -lh不在我使用的实际命令中,则以这种方式使用是有效的。如果我尝试它,+我会收到一条错误消息:

find: missing argument to '-exec'
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它会这样,或者正确的命令是什么。请不要只是发布命令更正,我想了解而不是盲目地遵循建议。

cha*_*aos 19

该帖子中的用户可能会说命令+末尾的符号-exec更快,但不是为什么。

让我们假设该find命令返回以下文件:

/path/to/file1
/path/to/file2
/path/to/file3
Run Code Online (Sandbox Code Playgroud)

普通-exec命令 ( -exec command {} \;) 对每个匹配的文件运行一次。例如:

find ... -exec mv {} /target/ \;
Run Code Online (Sandbox Code Playgroud)

执行:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/
Run Code Online (Sandbox Code Playgroud)

如果使用+符号 ( -exec command {} +),则通过在命令末尾添加多个匹配的文件来构建命令。例如:

find ... -exec mv -t /target/ {} +
Run Code Online (Sandbox Code Playgroud)

执行:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3
Run Code Online (Sandbox Code Playgroud)

+正确使用标志,要处理的参数必须位于命令的末尾,而不是中间。这就是为什么在您的示例中使用findtrows的原因missing argument to '-exec';它错过了结束{}


Wil*_*ilf 11

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

'+' exec 的终止符比 '\;' 快  见 https://askubuntu.com/questions/558817/what-is-the-difference-between-using-and-in-exec-command; 从原始文件创建备份文件是个好主意

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

将 -exec 与分号 ( find . -exec ls '{}' \;) 一起使用,将执行

ls file1
ls file2
ls file3
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用加号 ( find . -exec ls '{}' \+),则所有文件名都将作为参数传递给单个命令:

ls file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

还有其他可用的形式;和使用+(从这里:)

因此, find 命令允许使用以下示例语法:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +
Run Code Online (Sandbox Code Playgroud)

但是,我不确定这是否适用于 move 命令,因为它的语法是 mv [OPTION]... SOURCE DEST,除非使用-t选项或类似选项。然而,它应该ls在没有额外选项等的情况下工作,因为他们可以理解何时给出多个文件名。该+还可能需要进行转义(即\+