在 awk 中查找正则表达式

Find a regexp in awk

我有一个包含这样一行的文件:

<div class="cell contentCell bbActiveRow" tabindex="-1" style="width: 150px; left: 77px; display: block;" cellposition="15,2"><div class="cell contentCell bbActiveRow last-child" tabindex="-1" style="width: 150px; left: 697px; display: block;" cellposition="15,6">159</div></div><div class="contentRow bb_row" rowindex="16" style="display: block; top: 429px;"><div class="cell first-child " title="Go to box" tabindex="-1" role="linkAction" cellposition="16,0"><span class="pre-child" style="background-color:#16A765;">&nbsp;</span><span class="link" role="link">&nbsp;</span></div>

我想抓住的重要一点是:

中的 159
,6">159</div>

我可以用 grep 捕捉它:

cat c |grep  ',6\">[0-9]\+<'

现在,我想做的是实际捕获数字本身 (159) 并将其打印出来。 请注意,我拥有的实际文件中有几行。理想情况下,只会打印出数字。

我以为我可以用 awk 来做:

cat c | awk ' /,6\">([0-9]\+)/ { print  } '

但是没有,没有打印出来。 准备好正则表达式,并且知道文件中有几行条目与表达式匹配(具有不同的数字),您将如何压缩这些数字?

务实的方法:

cat c | grep -o ',6\">[0-9]\+<' | awk -F'<|>' '{ print  }'
  • -o 导致 grep 只报告每一行的匹配部分。
  • awk -F'<|>' '{ print }' 然后提取 >< 之间的标记。

至于为什么您的 awk 命令不起作用:

  • awk 使用扩展的正则表达式,其中 + 不能转义为 \+ 才能被识别为量词。
  • 即使修复了这个问题,该命令也无法正常工作,因为默认情况下,awk 按空格拆分,因此 </code> 将只报告第二个 <em> 空格</em> - 每个匹配行上的分隔标记,与导致匹配的正则表达式无关。</li> </ul> <hr> <p>顶部的解决方案甚至在一行中找到<em>多个</em>匹配项,但如果我们假设最多有1个,则它是<em>相对</em> 直接 <strong> 在 <code>awk 中完成所有操作, 如果 你有 GNU awk:

    cat c | gawk '{ m=gensub(/^.*,6\">([0-9]+)<.*$/, "\1", "1"); if (m != [=11=]) print m }'    
    
    • 非 POSIX gensub() 替换正则表达式匹配和 returns 替换,同时重要的是还支持反向引用,POSIX sub()gsub() 函数没有。
    • 上面匹配整行,然后仅用捕获的数字替换它(通过(转义)反向引用 </code>),并将结果存储在变量中。如果变量不等于输入行,则捕获匹配项并打印出来。</li> </ul> <p>虽然仅具有 POSIX <code>awk 功能的解决方案是可能的(使用 match()RSTARTRLENGTHsplit() ), 会很麻烦。


      最后,如果你有xmllint(OS X有,一些 Linux 发行版),请考虑 执行实际 HTML 解析并应用 XPath 查询的解决方案,因此更健壮。

这个 oneliner 是另一种方法(使用 xpath 表达式匹配 div 包含以 ',6' 结尾的 cellposition 属性值的元素):

# xmllint --html test.html --xpath '//div[substring(@cellposition, string-length(@cellposition) - 1)=",6"]/text()' 
159