find命令后如何集成mv命令?


60

我正在AAA使用以下命令搜索名称包含在其路径中的文件:

find path_A -name "*AAA*"

给定以上命令显示的输出,我想将这些文件移到另一个路径,例如path_B。我可以通过在find命令之后立即移动这些文件来优化命令,而不是一一移动这些文件吗?

Answers:


86

使用GNU mv

find path_A -name '*AAA*' -exec mv -t path_B {} +

这将使用find的-exec选项,该选项{}依次用每个查找结果替换,并运行您提供的命令。如中所述man find

   -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.  

在这种情况下,我们使用的+版本,-exec以便我们运行尽可能少的mv操作:

   -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 invoca‐
          tions 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.

不要忘记“ \;” 在执行程序的结尾!
查尔斯·罗斯

@Charles Roth:+是工作的结束者,您可以在上面阅读我的报价,也可以man find代替
cuonglm

谢谢你!我试图用-exec mv {} path_b +它与权限错误失败。TBH,我仍然不明白为什么,但是-exec mv -t path_b {} +请客!
杰里米·戴维斯

6
@JeremyDavis使用时-exec ... {} +{}必须是之前的最后一件事+。这就是为什么他mv -t destdir {} +不使用mv {} destdir +-exec mv {} destdir ';'取而代之的是感冒,但是mv每个文件执行一次。
库萨兰达

23

您也可以执行以下操作。

find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B

哪里,

  1. -0如果有空格或字符(包括换行符),则许多命令将不起作用。此选项照顾空格的文件名。
  2. -I将初始参数中出现的replace-str替换为从标准输入中读取的名称。同样,未加引号的空格也不会终止输入项目。相反,分隔符是换行符。

测试中

我创建了两个目录as sourcedirdestdir。现在,我创建的文件里面一堆sourcedirfile1.bakfile2.bakfile3 with spaces.bak

现在,我执行命令为

find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/

现在,里面的destdir,当我这样做ls,我可以看到文件已经从移动sourcedirdestdir

参考文献

http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/


22

为了使OS X用户遇到此问题,OS X中的语法略有不同。假设您不想在以下子目录中递归搜索path_A

find path_A -maxdepth 1 -name "*AAA*" -exec mv {} path_B \;

如果要递归搜索所有文件path_A

find path_A -name "*AAA*" -exec mv {} path_B \;

这不是OS X特定的语法,与find我使用的语法相同。优点:(-maxdepth特别是如果path_B是子目录-避免mv尝试将文件移到那里!)并使用\; (因此{}不必是最后一个参数,并且mv可以使用常规语法)
drevicko

6

-exec是执行此操作的最佳方法。如果出于某种原因这不是一个选择,那么您还可以循环读取结果:

find path_A -name "*AAA*" -print0 | 
    while IFS= read -r -d $'\0' file; do mv "$file" path_B; done

这是安全的方法,它可以处理包含空格,换行符或其他奇怪字符的文件名。一种简单的方法,但是除非您的文件名仅由简单的字母数字字符组成否则该方法将失败,是

mv $(find path_A -name "*AAA*") path_B

但是使用while循环。


如果your file names consist only of simple alphanumeric characters,例如,如果到达ARG_MAX


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.