grep 中的“+”问题

grep 中的“+”问题

我正在尝试编写一个 grep 命令来在大型文本文件中查找如下行:

<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle">

但该+符号似乎在以下命令中引起了问题:

 grep 'data=[a-z,0-9,\"]' file

大量热门歌曲

 grep 'data=[a-z,0-9,\"]+' file

没有命中

答案1

如果您想要+表示“一个或多个前述原子”,那么您必须执行以下其中一项操作:

  1. 使用-E(扩展正则表达式)(或-P,PCRE):

    grep -E 'data=[a-z,0-9,\"]+' file
    
  2. 转义+,以便在默认使用的基本正则表达式中得到特殊处理grep

    grep 'data=[a-z,0-9,"]\+' file
    

答案2

要点:

  • +是一个 ERE(扩展正则表达式)标记,它表示前面的一个或多个标记,如果使用-E选项,则可以使用该标记;如果使用 BRE(基本正则表达式),则可以使用转义的 ),即只有正则grep(\+grep

  • 字符类将匹配、、或[a-z,0-9,\"]之间的任何字符。这可能不是您想要的[a-z][0-9],"

  • 正常情况下grep输出整行,如果只想输出匹配的部分,请-o使用grep


根据您的示例,您可以执行以下操作:

grep -E '\bdata=[a-z0-9"]+\b' file
  • -E启用 ERE
  • \b匹配字符串边缘,零宽度
  • data=data=字面匹配
  • [a-z0-9"][a-z]匹配、[0-9]和中的任何字符"+匹配前一个标记一次或多次

即使您使当前的模式正确,但如果没有这个模式,\b就会出现诸如 之类的误报。foo fdata=2322abdata=12AB

例子:

% grep -oE '\bdata=[a-z0-9"]+\b' <<<'<div class="node_thumbnail" data-type="file" name="GOPR0036.MP4_frame000001.jpg" data="813334c25191468c9f1c57afc99fde60" aid="133948" rel="/Files/ToolTipView?fileId=813334c25191468c9f1c57afc99fde60&pageNo=1&NoCache=101016083044" rev="topMiddle"'
data="813334c25191468c9f1c57afc99fde60

答案3

另一个选择是使用 egrep:

egrep 'data=[a-z,0-9,\"]+' file

egrep 与 grep 捆绑在一起,它只是 grep 的一个包装器:

#!/bin/sh
exec grep -E "$@"

这对于交互式使用来说很好。但是在脚本中我会使用grep -E

相关内容