【问题标题】:How can I have grep not print out 'No such file or directory' errors?我怎样才能让 grep 不打印出“没有这样的文件或目录”错误?
【发布时间】:2011-06-21 13:48:50
【问题描述】:

我正在通过 git 管理的一大堆代码进行 grep,每当我执行 grep 时,我都会看到成堆的表单消息:

> grep pattern * -R -n
whatever/.git/svn: No such file or directory

有什么办法可以让这些线条消失吗?

【问题讨论】:

  • 这些天我建议使用agackcgrep 代替 - 它们比grep 更快/更好地搜索代码存储库。
  • 如果您正在浏览代码并希望避免特定目录,也许您应该查看 ack.这是一个可识别源代码的 grep,因此会主动忽略此类 VCS 目录(以及 vi 和 emacs 备份、非源文件等)。
  • 用户如何获得No such file or directory 消息以获取存在的文件和/或目录?或者,相反地,grep * 如何获取不存在的文件名?这是一种竞争条件,在 grep 运行时,其他一些进程会操纵目录树(创建、重命名和删除文件)?

标签: grep


【解决方案1】:

您可以使用-s--no-messages 标志来抑制错误。

-s, --no-messages 抑制错误消息

grep pattern * -s -R -n

【讨论】:

  • @Alex @Dogbert 这确实回答了这个问题,但是“-s”可以掩盖问题,例如当您将 xargs 与 grep 一起使用时。尝试在目录中创建 2 个文件,'aaa.txt' 和 'a b.txt',它们都包含字符串 'some text'。命令/bin/ls -1 | xargs grep 'some text' 会给你“没有这样的文件或目录”,因为它将'a b.txt' 分解为2 个参数。如果你压制,你不会注意到你错过了一个文件。
  • @Kelvin 可以,例如如果我使用find 并使用print0xargs -0 是否可以解决问题?谢谢
  • @Luka 这应该可以解决问题。如果您始终使用这些 NUL 选项,您不会遇到问题,但如果您不使用,几乎可以保证(恕我直言)您会在最不合时宜的时候忘记。
  • 这适用于其他选项(--quiet)不支持的 Mac OS X
  • @Luka 如果你使用 find 你可以省略 xargs 并从 find 使用 -exec (如果你需要 shell 工具你可以用你最喜欢的 shell 包装你的命令)
【解决方案2】:

如果您正在浏览 git 存储库,我建议您使用 git grep。不需要传入-R 或路径。

git grep pattern

这将显示当前目录下的所有匹配项。

【讨论】:

  • +1 表示有用的特定于 git 的命令。虽然不适用于 svn :-)
  • +1 这是我一直缺少的 git 命令 - 这让我可以在任何提交中从树的状态中 grep 字符串(通过在“模式”之后添加提交)。
  • 使用 fugitive 插件,Ggrep 也会从 Git 目录的顶部开始搜索,而不是从当前目录开始。
  • 这似乎比标准 grep 快得多。 (也许它忽略了二进制文件等?不知道,但很有用。)
【解决方案3】:

这样的错误通常被发送到“标准错误”流,您可以通过管道传输到文件或在大多数命令中使其消失:

grep pattern * -R -n 2>/dev/null

【讨论】:

  • 回答问题,但可以掩盖问题。在 Dogbert 的回答下查看我的评论。
【解决方案4】:

我已经看到这种情况发生了好几次,由于链接断开(指向不存在文件的符号链接),grep 尝试搜索不存在的目标文件(因此出现正确和准确的错误消息)。

我通常不会在通过控制台执行系统管理员任务时打扰,但我确实会在脚本中使用“find”查找文本文件,然后对每个文件进行 grep:

find /etc -type f -exec grep -nHi -e "widehat" {} \;

代替:

grep -nRHi -e "widehat" /etc

【讨论】:

    【解决方案5】:

    我通常不让 grep 自己进行递归。通常有几个目录是你想跳过的(.git、.svn...)

    你可以用这样的姿势做聪明的别名:

    find . \( -name .svn -o -name .git \) -prune -o -type f -exec grep -Hn pattern {} \;
    

    乍一看可能有点矫枉过正,但当你需要过滤掉一些模式时,它就很方便了。

    【讨论】:

    • +1。这比抑制错误要好得多。但是,我认为您在 grep 之前忘记了 -exec
    • 这是什么意思? \( -name .svn -o -name .git \)
    • 为什么不使用 grep 的 --exclude 或 --exlcude-dir 标志?
    • @sbhatla 括号为 find 命令创建操作顺序。 stackoverflow.com/questions/24338777/…
    【解决方案6】:

    您是否尝试过 xargs 中的-0 选项?像这样的:

    ls -r1 | xargs -0 grep 'some text'
    

    【讨论】:

    • 为了找到你应该添加 -print0 find -print0 | xargs -0 grep 'text'
    【解决方案7】:

    在 grep 中使用 -I

    例如:grep SEARCH_ME -Irs ~/logs

    【讨论】:

    • -I 跳过二进制文件 - 它等同于 --binary-files=without-match。但它不会抑制“没有这样的文件或目录”消息。
    【解决方案8】:

    我将 stderr 重定向到 stdout,然后使用 grep 的反转匹配 (-v) 排除我想要隐藏的警告/错误字符串:

    grep -r <pattern> * 2>&1 | grep -v "No such file or directory"
    

    【讨论】:

      【解决方案9】:

      我在 PATH 中使用 /Git/usr/bin 从 Windows 上的 Emacs 运行“M-x rgrep”时遇到很多错误。显然在这种情况下,M-x rgrep uses "NUL" (the Windows null device) rather than "/dev/null"。我通过将其添加到 .emacs 来解决此问题:

      ;; Prevent issues with the Windows null device (NUL)
      ;; when using cygwin find with rgrep.
      (defadvice grep-compute-defaults (around grep-compute-defaults-advice-null-device)
        "Use cygwin's /dev/null as the null-device."
        (let ((null-device "/dev/null"))
          ad-do-it))
      (ad-activate 'grep-compute-defaults)
      

      【讨论】:

        【解决方案10】:

        让 grep 始终返回零状态的一种简单方法是使用 || true

         → echo "Hello" | grep "This won't be found" || true
        
         → echo $?
           0
        

        如您所见,这里的输出值为 0(成功)

        【讨论】:

          猜你喜欢
          • 2017-10-28
          • 1970-01-01
          • 1970-01-01
          • 2021-12-31
          • 2021-10-31
          • 1970-01-01
          • 2018-08-14
          • 1970-01-01
          • 2021-04-18
          相关资源
          最近更新 更多