【问题标题】:Why doesn't my 'find' work like I expect using -exec?为什么我的“查找”工作不像我期望的那样使用 -exec?
【发布时间】:2010-10-13 21:30:33
【问题描述】:

我正在尝试从工作目录中删除所有 .svn 目录。

我以为我会像这样使用 find 和 rm:

find . -iname .svn -exec 'rm -rf {}' \;

但结果是:

find: rm -rf ./src/.svn: 没有那个文件或目录

显然该文件存在,或者 find 找不到它...我错过了什么?

【问题讨论】:

  • 如果可以的话,你真的应该使用 -delete 和 find。使用 -delete 或 rm -rf 时不要忘记将 -depth 与 find 一起使用。
  • 根据手册页看起来 -delete 意味着 -depth。

标签: unix shell find


【解决方案1】:

您不应将rm -rf {} 放在单引号中。

正如您所引用的,shell 将 -exec 它的所有参数视为命令而不是命令加参数,因此它正在寻找一个名为 "rm -rf ./src/.svn" 的文件,但没有找到它。

试试:

find . -iname .svn -exec rm -rf {} \;

【讨论】:

  • 我认为我最后一次使用 -exec 是为了一个 grep,我需要引用正则表达式,所以我脑子里有这个。谢谢大家!
  • 我说“不需要”,因为看起来 Sam 认为他需要这样做。但是,我发现这是模棱两可的,将进行编辑。
【解决方案2】:

顺便说一句,您可能应该改掉使用 -exec 来处理可以同时对多个文件执行的操作的习惯。例如,出于习惯,我会把它写成

find . -iname .svn -print | xargs rm -rf

或者,因为我现在使用的是 Macintosh,并且更有可能遇到带有空格的文件或目录名称

find . -iname .svn -print0 | xargs -0 rm -rf 

"xargs" 确保每个“N”个文件只调用一次“rm”,其中“N”通常是 20。在这种情况下,这并不是一个巨大的胜利,因为 rm 很小,但如果你想要的程序在每个文件上执行很大或在启动时进行大量处理,它可以使事情变得更快。

【讨论】:

  • 太棒了。我将查看 xargs 的手册页,作为记录,我也在 Mac 上。 w00t!
  • 另外,您可以使用“\+”而不是“\;”结束 find 的 -exec 子句,这相当于使用 -print0 和管道到 xargs。
  • @Adam,那一定很新?请注意,在 Ultrix 时代,我在 MicroVax 上转而使用 args,因此“新”可能意味着“在过去 15-20 年”。
【解决方案3】:

也许只有我一个人,但是旧的 find & rm 脚本在我当前的配置上工作,a la:

find /data/bin/test -type d -mtime +10 -name "[0-9]*" -exec rm -rf {} \;

而 xargs 解决方案确实,a la:

find /data/bin/test -type d -mtime +10 -name '[0-9]*' -print | xargs rm -rf ;

不知道为什么,但我已经更新了我的 scriptLib,所以我不会再花几个小时殴打 我想到了这么简单的事情......

(在 kernel-2.6.18-194.11.3.el5 下运行 RHEL)

编辑:找出原因 - 我的 RHEL 发行版默认 vi 将可怕的 cr 插入换行符(其中中断命令) - 遵循 linuxquestions.org 上 nx5000 和 jliagre 的建议,添加了以下内容到 ~/.vimrc:

:设置文件格式=unix

映射 :set fileformat=unix

映射 :set fileformat=dos

允许行为以 F4/F5 为中心。

检查 CR 是否嵌入到您的文件中:

head -1 scriptFile.sh | od -c |头 -1

http://www.linuxquestions.org/questions/linux-general-1/bad-interpreter-no-such-file-or-directory-213617/

【讨论】:

    【解决方案4】:

    你也可以使用svn命令如下:

    svn export <url-to-repo> <dest-path>
    

    Look here for more info.

    【讨论】:

    • 太棒了。我想我可以做到,但我不知道如何导出工作目录。谢谢!
    【解决方案5】:

    试试

    find . -iname .svn -exec rm -rf {} \;
    

    这可能应该适用于 IIRC。

    【讨论】:

      【解决方案6】:

      您可以使用以下技巧在引号中传递任何您想要的内容。

      find . -iname .svn -exec bash -c 'rm -rf {}' \;
      

      exec 选项会很高兴看到您只是在调用带有参数的可执行文件,但您的参数将能够包含基本上任何大小和形状的脚本。

      find . -iname .svn -exec bash -c '
        ls -l "{}" | wc -l
      ' \;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-16
        • 2022-11-12
        • 1970-01-01
        • 2021-11-19
        • 2016-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多