在awk中找到一个正则表达式

时间:2015-02-18 02:09:02

标签: regex shell 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 in:

,6">159</div>

我可以用grep抓住它:

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

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

我以为我可以用awk做到这一点:

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

但不,没有任何东西被打印出来。 准备好regexp,并且知道文件中有几行与条目匹配的条目(具有不同的数字),你会如何挤出这些数字?

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

务实的方法:

cat c | grep -o ',6\">[0-9]\+<' | awk -F'<|>' '{ print $2 }'
  • -o会导致grep仅报告每行的匹配部分。
  • awk -F'<|>' '{ print $2 }'然后在><之间提取令牌。

至于你的awk命令无效的原因:

  • awk使用扩展正则表达式,其中+不得转义为\+,以便将其识别为量词。
  • 即使修复了该命令,该命令也无法正常工作,因为默认情况下,awk按空格分割,因此$2只会报告第二个空白 - 不管导致匹配的正则表达式,每条匹配行上的分隔标记。

顶部的解决方案甚至可以在一行上找到多个匹配,但是如果我们假设最多只有1个,那么它相对直接< strong>在awk 中完成所有操作,如果你有 GNU awk

cat c | gawk '{ m=gensub(/^.*,6\">([0-9]+)<.*$/, "\\1", "1"); if (m != $0) print m }'    
  • 非POSIX gensub()替换正则表达式匹配并返回替换,同时关键还支持反向引用,POSIX sub()gsub()函数不支持。
  • 以上匹配整行,然后将其替换为仅捕获的数字(通过(转义)反向引用\1),并将结果存储在变量中。如果变量不等于输入行,则捕获匹配,然后打印。

虽然只能使用POSIX awk功能的解决方案(使用match()RSTARTRLENGTHsplit()),但这会很麻烦。< / p>


最后,如果你有xmllint(OS X有,并且某些 Linux发行版),请考虑guido's answer以获得执行实际的解决方案HTML解析并应用XPath查询,因此更加健壮。