首先,我正在使用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"/>
答案 0 :(得分:2)
要解析/查询XML / XHTML文档,请使用以下工具之一:
我会使用xmlstarlet
建议解决方案
1)安装xmlstarlet
工具
2)使用 XmlStarlet select
或sel
选项查询或搜索 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语法,你就会得到一把锤子,一切看起来像钉子。