为什么find -exec mv {} ./target/ +不工作? (在cygwin上) [英] Why does find -exec mv {} ./target/ + not work ? (on cygwin)

查看:371
本文介绍了为什么find -exec mv {} ./target/ +不工作? (在cygwin上)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道 {} \; {} \ + | xargs ... do。请澄清这些解释。



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

 查找。 -type f -exec file {} \; 
find。 -type f -exec file {} \ +
find。型f | xargs文件

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

 文件file1.txt 
文件file2.txt

但是后面的两个查找与 -exec 命令运行文件命令一次所有文件如下所示:

 文件file1.txt file2.txt 

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

  find。 -type f -iname'* .cpp'-exec mv {} ./test/ \; 
find。 -type f -iname'* .cpp'-exec mv {} ./test/ \ + #gives错误:find:缺少'-exec'参数

对于 {} \ + 的命令,它给出错误消息

  find:`-exec'缺少参数


$ b b

为什么?任何人都可以解释我做错了什么?

解决方案

手册页几乎解释了一切。



find -exec command {} \;



对于每个结果, command {} 被执行。所有出现的 {} 由文件名替换。

查找-exec命令{} + ; 以前面加上斜杠以防止shell解释。 / h2>

每个结果都附加到命令后执行。考虑到命令长度限制,我想这个命令可以执行更多次,手册页面支持我:



请从手册页注意此引用:

p>


命令行的构建方式与xargs构建其命令行非常相似


这就是为什么除了空格外, {} + 之间不允许有字符。 + 使查找检测到参数应该附加到命令,如 xargs



解决方案



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

  mv -t target file1 file2 ... 

您的命令变成:

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






从手册页:


-exec命令;



执行命令;如果返回0状态,则返回true。发现的所有后面的参数被认为是命令的参数,直到遇到由;'组成的参数。字符串 {}'将替换为在命令的参数中出现的当前文件名,而不仅仅是在某些版本的find中的参数中。这两个结构可能需要转义(使用`\')或引用,以防止它们被shell扩展。有关使用-exec选项的示例,请参见示例部分。指定的命令对每个匹配的文件运行一次。该命令在起始目录中执行。围绕使用-exec操作有不可避免的安全问题;您应该改用-execdir选项。



-exec command {} +



exec操作在选定的文件上运行指定的命令,但命令行是通过在末尾附加每个选定的文件名来构建的;该命令的调用的总数将远小于匹配的文件的数目。命令行的构建方式与xargs构建命令行的方式非常相似。在命令中只允许使用一个`{}'实例。该命令在起始目录中执行。



I want to know exactly what {} \; and {} \+ and | xargs ... do. Please clarify these with explanations.

Below 3 commands run and output same result but the first command takes a little time and the format is also little different.

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

It's because 1st one runs the file command for every file coming from the find command. So, basically it runs as:

file file1.txt
file file2.txt

But latter 2 find with -exec commands run file command once for all files like below:

file file1.txt file2.txt

Then I run the following commands on which first one runs without problem but second one gives error message.

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

For command with {} \+, it gives me the error message

find: missing argument to `-exec'

why is that? can anyone please explain what am I doing wrong?

解决方案

The manual page pretty much explains everything.

find -exec command {} \;

For each result, command {} is executed. All occurences of {} are replaced by the filename. ; is prefixed with a slash to prevent the shell from interpreting it.

find -exec command {} +

Each result is appended to command and executed afterwards. Taking the command length limitations into account, I guess that this command may be executed more times, with the manual page supporting me:

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

Note this quote from the manual page:

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

That's why no characters are allowed between {} and + except for whitespace. + makes find detect that the arguments should be appended to the command just like xargs.

The solution

Luckily, mv can accept the target directory as an argument, with either -t or the longer parameter --target. It's usage will be:

mv -t target file1 file2 ...

Your find command becomes:

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


From the manual page:

-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 con‐ structions 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.

这篇关于为什么find -exec mv {} ./target/ +不工作? (在cygwin上)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆