【问题标题】:grep --include command doesn't work in OSX Zshgrep --include 命令在 OSX Zsh 中不起作用
【发布时间】:2014-08-03 12:47:01
【问题描述】:

我正在关注How do I find all files containing specific text on Linux? 上的最佳答案以在我的项目中搜索字符串。

这是我的命令grep --include=*.rb -rnw . -e "pattern"

Zsh 告诉我zsh: no matches found: --include=*.rb

grep 好像不支持--include 选项。

当我输入grep --help 时,它会返回

usage: grep [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
    [-e pattern] [-f file] [--binary-files=value] [--color=when]
    [--context[=num]] [--directories=action] [--label] [--line-buffered]
    [--null] [pattern] [file ...]

这里没有--include

我的 grep 版本是否太旧?还是我的命令有问题?

【问题讨论】:

    标签: macos grep zsh


    【解决方案1】:

    FreeBSD/macOS grep确实支持--include选项(参见man grep;不幸的是命令行帮助(grep -h)不支持't list this option),但您的问题是选项参数 *.rb 没有被引用

    因此,您的 shellzsh尝试预先扩展路径名 --include=*.rb,但失败了,因为当前目录包含没有名称与 glob 模式 *.rb 匹配的文件。
    grep 甚至永远不会执行。

    由于您的意图是将*.rb 未经修改地传递给grep,因此您必须引用

    grep --include='*.rb' -rnw . -e "pattern"     
    

    要包含 多个 glob

    • 为每个传递一个--include 选项;例如:

      grep --include='*.rb' --include=='*.h*' -rnw . -e "pattern"     
      
    • 或者,在支持大括号扩展的shell中 - 特别是bashkshzsh - 你可以让你的shell em> 为您创建这些多个选项,如下所示 - 注意选择性引用(有关详细说明,请参阅this answer):

      grep '--include=*.'{rb,'h*'} -rnw . -e "pattern"     
      

    【讨论】:

    • 仍然无法修复模式`grep 'pattern' -rIn '--include=*.{c*,h*}'``
    • @linzuojian,您正在尝试使用 brace 扩展,它 (a) 只有 一些 shell 支持并且 (b) 只有在使用时才支持 未引用。 grep 本身理解这个符号。请参阅我的更新,其中显示了如何正确使用大括号扩展,并链接到带有背景信息的答案。
    【解决方案2】:

    如果您的grep 不支持--include,并且您不想为此安装GNU grep,则有许多可移植的方法来执行相同的操作。顶一下,试试吧

    find . -type f -name '*.rb' -exec grep -nw "pattern" /dev/null {} \;
    

    find 命令遍历目录(如grep -r)查找名为*.rb 的文件(如--include 选项),/dev/null 很有用,因为grep 显示的输出格式略有不同你在多个文件上运行它。

    这有点低效,因为它为每个文件运行一个单独的grep。如果速度太慢,请查看xargs(如果您的find 支持,请使用find -exec ... {} \+ 而不是... {} \;)。这是一个非常常见的任务;您应该可以轻松找到数千个示例。

    您可能还想考虑ack,这是一种流行且对用户更友好的替代方案。它是独立的,因此“安装”相当于将其复制到您的$HOME/bin

    【讨论】:

    • 否:FreeBSD支持--include;它只是没有在 命令行 帮助中列出(但在man grep 中); OP 的问题是使用 unquoted glob *.rb。为避免多次grep 调用的低效率,只需使用+ 而不是\;,这会为您提供xargs 类似的行为:find . -type f -name '*.rb' -exec grep -nw "pattern" {} +。感谢ack 的提示 - 没听说过。
    • 感谢您的更新。我不确定osx 支持什么以及zsh 带来了什么。在答案中添加了find ... -exec ... \+;感谢您指出这一点。
    • 我的荣幸;你说关于+ 功能:if your find supports that;实际上,它是 POSIX 的一部分 - 请参阅 man.cx/find。你介意修改你的介绍,不再建议只有 GNU grep支持--include吗?
    • 标准与否,我有 GNU find 太旧以至于不支持 -exec ... \+ 的盒子(GNU find 4.1.20,Debian 3.1 [原文如此])
    • 很有趣,谢谢你告诉我。 (小题外话:\; 中的 \ 仅用于保护 ; 不被 shell 解释(作为命令分隔符) - \ 被shell 和find 只能看到;。由于+ 对shell 来说不是特殊的,所以不需要这样转义(尽管它也没有任何危害),所以-exec ... {} + 会这样做。但是,我可以看到有人可能会选择仍然使用它来实现对称性,而不必记住特殊情况。)
    猜你喜欢
    • 2018-11-24
    • 2023-02-05
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2018-10-26
    • 2017-08-20
    • 2016-01-20
    相关资源
    最近更新 更多