linux - 为什么 find -exec mv {} ./target/+ 不起作用?

我想知道 {}\;{}\+| 到底是什么xargs ... 做。请用解释澄清这些。

以下 3 个命令运行并输出相同的结果,但第一个命令需要一点时间,格式也略有不同。

find . -type f -exec file {} \;
find . -type f -exec file {} \+
find . -type f | xargs file

这是因为第一个对来自 find 命令的每个文件运行 file 命令。所以,基本上它运行为:

file file1.txt
file file2.txt

但后 2 个 find 使用 -exec 命令对所有文件运行一次文件命令,如下所示:

file file1.txt file2.txt

然后我运行以下命令,第一个运行没有问题,但第二个给出错误消息。

find . -type f -iname '*.cpp' -exec mv {} ./test/ \;
find . -type f -iname '*.cpp' -exec mv {} ./test/ \+ #gives error:find: missing argument to `-exec'

对于带有 {}\+ 的命令,它会给我错误消息

find: missing argument to `-exec'

这是为什么呢?谁能解释一下我做错了什么?

最佳答案

manual page (或 online GNU manual )几乎可以解释一切。

find -exec 命令 {}\;

对于每个结果,都会执行 command {}。所有出现的 {} 都被文件名替换。 ; 以斜杠为前缀,以防止 shell 解释它。

find -exec 命令 {} +

每个结果都附加到 command 并随后执行。考虑到命令长度限制,我猜这个命令可能会执行更多次,手册页支持我:

the total number of invocations of the command will be much less than the number of matched files.

请注意手册页中的这句话:

The command line is built in much the same way that xargs builds its command lines

这就是为什么 {}+ 之间除了空格之外不允许使用任何字符的原因。 + 使 find 检测到参数应该附加到命令中,就像 xargs 一样。

解决方案

幸运的是,mv 的 GNU 实现可以接受目标目录作为参数,使用 -t 或更长的参数 --target。它的用法是:

mv -t target file1 file2 ...

你的 find 命令变成:

find . -type f -iname '*.cpp' -exec mv -t ./test/ {} \+

来自手册页:

-exec command ;

Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountered. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a `\') or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.

-exec command {} +

This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invocations of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.

https://stackoverflow.com/questions/5607542/

相关文章:

linux - 为Linux目录下新创建的文件和子目录设置默认权限?

python - Python中的多级 'collection.defaultdict'

python - 为什么函数可以修改调用者感知的某些参数,而不能修改其他参数?

linux - 如何链接到特定的 glibc 版本?

linux - 如何仅在脚本期间设置环境变量?

python - 将迭代器转换为列表的最快方法

python - 为什么我们不应该在 py 脚本中使用 sys.setdefaultencoding

linux - 如何使用 Red Hat Linux 上的标准工具随机化文件中的行?

linux - 在新的 linux 内核中上下文切换要慢得多

python - Python 中 dict.clear() 和分配 {} 的区别