使用egrep但开始认为awk或sed可能是解决方案

时间:2017-03-11 22:48:19

标签: awk sed grep posix

首先,我正在使用Cygwin mintty 2.7.4所以... posix。我有一个类似于以下文件的多个代码片段:

<blah>Spread the peanut butter <ramout assot="f0123_fun10" bapel="2 or 6"/> on good looking bread <ramout assot="f0123_fun10" bapel="3 or 5"/> that does not have peanut butter <ramout assot="f0123_fun10" bapel="2 or 6"/> already on the bread this that and the other <ramout assot="f0123_fun10" bapel="4"/> with something else.</blah>

我试图在一组blah标签中找到ramout标签的重复实例。 如果存在以下内容:

<ramout assot="f0123_fun10" bapel="2 or 6"/> 

我想知道它是否在一组打开和关闭的blah标签中再次重复。

我尝试过多种方法。最新的一个是以下内容:

grep -Eoi '<blah>.*([[:space:]]<ramout assot).*\1.*</blah>' *.xml | less

没有返回任何内容。

我也尝试过:

 grep -Eio '<blah>.*([[:space:]]<ramout assot="[a-z][0-9]{5}_fig[0-9]+" bapel="[0-9]+.*)' *.xml

不包括网络结果但不显示所有结果的反向引用。看起来这只是显示一行/不跨越多行的结果。

如果我想搜索可能在一行上的东西,我应该使用sed吗?

awk是否可行?我看到并尝试过:awk&#39; / Start pattern /,/ End pattern /&#39;文件名返回了更多结果,但我仍然没有得到所有结果。

任何帮助都能找到a)所有ramout结果在整个文件中,并且单独b)所有rahout结果在blah标签中都是重复的。

预期结果如下:

搜索结果a)显示所有ramout结果:

<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="3 or 5"/>
<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="4"/>

搜索结果b)显示重复结果显示:

<ramout assot="f0123_fun10" bapel="2 or 6"/>

2 个答案:

答案 0 :(得分:2)

要解析/查询XML / XHTML文档,请使用以下工具之一:

  • xmlstarlet
  • xmllint
  • 撒克逊皮棉

我会使用xmlstarlet建议解决方案 1)安装xmlstarlet工具
2)使用 XmlStarlet selectsel选项查询或搜索 XML 文档(xmlstarlet manual

a)整个文件中的所有<ramout>个标签:

xmlstarlet sel -t -n  -m "//blah/ramout" -c "." -n testfile.xml

输出:

<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="3 or 5"/>
<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="4"/>

b) <ramout>代码中重复的所有<blah>个代码:

xmlstarlet sel -t -n  -m "//blah/ramout" -c "." -n testfile.xml | sort | uniq -d

输出:

<ramout assot="f0123_fun10" bapel="2 or 6"/>

uniq -d
 -d, --repeated - 仅打印重复的行,每个组一个

答案 1 :(得分:0)

a) sed 's/</\n</g;s/>/>\n/g' pb.txt | sed -n '/<blah/,/<\/blah/{/ramout/p}'

第一个sed调用只是确保标记周围的换行符。第二次调用打印ramout个标记之间的每个blah行。语法为/START/,/END/{/MATCH/p},意思是从START到END,打印MATCH的行。

所以你明白了:

<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="3 or 5"/>
<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="4"/>

在建立xmlstarlet答案后,您可以将其传递给sort,然后uniq -d

b) sed 's/</\n</g;s/>/>\n/g' pb.txt | sed -n '/<blah/,/<\/blah/{/ramout/p}' | sort | uniq -d

对于此输出:

<ramout assot="f0123_fun10" bapel="2 or 6"/>

+1 xmlstarlet的答案,因为这是正确的做事方式,并建立了sort | uniq -d。但是,如果你知道这种sed语法,你就会得到一把锤子,一切看起来像钉子。