如何在 grep 搜索中同时搜索单引号和双引号?

如何在 grep 搜索中同时搜索单引号和双引号?

bindkey当我在插件目录中搜索zsh关键冲突时,我会从.zsh脚本文件和.md文件中得到响应,并且一些 zsh 自述文件在bindkey语句中使用双引号。

'我如何使用和进行引用来搜索绑定键"?例如,如果Ctrl-R使用双引号作为匹配字符串来搜索第一个命令的用法,则会生成README.mdof zsh-navigation-tools,单引号会生成bindkeyvi-mode和v 的命令zsh-navigation-tools

grep -r -i 'bindkey "^r' ~/.oh-my-zsh/plugins

输出:

zsh-navigation-tools/README.md:    bindkey "^R" znt-history-widget
grep -r -i "bindkey '^r" ~/.oh-my-zsh/plugins

输出:

vi-mode/vi-mode.plugin.zsh:bindkey '^r' history-incremental-search-backward
zsh-navigation-tools/zsh-navigation-tools.plugin.zsh:bindkey '^R' znt-history-widget

如何创建输出所有 3 个命令的命令?

grep 是否可以选择指定一个备用引号字符,以允许'"作为文字?

答案1

使用P( --perl-regexp) 选项和字符类[...]

grep -Pri 'bindkey [\047\042]\^r' ~/.oh-my-zsh/plugins

  • [\047\042]- 匹配单引号\047或双引号\042

答案2

当然,你需要转义^字符:

grep -r 'bindkey "\^r' dir

然后,您可以使用“扩展正则表达式”替代字符“|”:

grep -E 'bindkey "\^r''|'"bindkey '\^r"  dir

可以简化为:

grep -E 'bindkey ("|'"')"'\^r' dir [1]

或者,如果使用 bash、ksh 或 zsh,请使用$'引号(' 和 " 都可以转义):

grep -E $'bindkey (\"|\')\^r' dir

最后,意识到有两个r:rR:

grep -rE $'bindkey (\"|\')\^(r|R)' dir

或者使用i(但这也会改变其他字符):

grep -riE $'bindkey (\"|\')\^r' dir

当然,这也是一个 perl 正则表达式(GNU grep):

grep -rP $'bindkey (\"|\')\^(r|R)' dir

[1]引用的内容可能很难理解。
但这只是三个引用部分的串联。
用单引号引起来的字符串,后跟用双引号引起来的字符串,后跟再次用单引号引起来的第三个字符串。查看效果的最简单方法是回显它。 shell 将删除一级引用,命令实际接收到的字符串将变得清晰:

$ echo grep -E 'bindkey ("|'   "')"   '\^r' dir
grep -E  bindkey ("|   ')   \^r dir

也许这样会更容易看到:

$ echo grep -E 'a'"b"'c' dir
grep -E abc dir

同样的内容也可以写在一对单引号中。
请记住,单引号内不能包含单引号:

$ echo grep -E 'bindkey ("|'\'')\^r' dir
grep -E bindkey ("|')\^r dir

或者在双引号内(双引号可以在双引号内转义)。增加的风险是一些其他字符($、`、\、* 和 @)在双引号内(不在单引号内)具有特殊含义:

$ echo grep -E "bindkey (\"|')\^r" dir
grep -E bindkey ("|')\^r dir

另一种方法是使用[…]带有\'和 的字符列表\"

$ grep -E 'bindkey '[\"\']'\^r' dir

这仍然是一个由三部分组成的字符串,但中间没有引号(并且没有空格):

'bindkey '    [\"\']     '\^r'

答案3

您可以在由双引号分隔的文本内转义双引号。

所以这个模式"[\"']"将匹配"- 或'

例如:


$ echo "'a'" | grep "[\"']a[\"']"
$ echo '"a"' | grep "[\"']a[\"']"
$ echo -e "\"thing\"\n'thing'\nthing" | grep -E "('thing'|\"thing\")"

TD;DR;

您可以在环境变量中定义模式,然后在调用 grep 命令时使用双引号来扩展变量。

假设您在 HTML 中查看标题属性中包含的文本,该文本可能以 ' 或 " 开头并以 ' 或 " 结尾。所以你的模式可能是以下之一:

$ title=["'].*["']     # (Greddy)
$ title=["'].*?["']    # (Non greddy)
$ title=["'][^"']*["'] # ("Non greddy" using negagation)

因此,您选择最佳模式并将其保存到变量中,然后使用该变量在调用 grep 命令时指定模式。

$ pattern="title=[\"'].*[\"']" # DO MIND ESCAPING THE INNER DOUBLE QUOTES (as they "outer" double quotes are used to define the text boundaries)
$ grep $pattern file

希望这对将来的任何人都有帮助!

相关内容