我最近遇到了一个问题,我似乎找不到一致的解决方案。
假设我们有一些xml文件,它的构建如下:
...
<tenant>
<name>bla</name>
<id>1</id>
<something>whatever</something>
</tenant>
<tenant>
<name>foo</name>
<id>55</id>
<something>whatever</something>
</tenant>
<tenant>
<name>waaaaaaaaaaaaaaaey</name>
<id>8013</id>
<something>what</something>
</tenant>
...
让我们说甚至可能有更多选项,如<e-mail>
和其他一些东西。所以它真的可以改变那里的长度。
现在我们知道它是“什么”的“东西”和它的grep。但我们不仅希望获得该结果,而且希望<tenant>
和</tenant>
之间的所有结果都包含<something>whatever</something>
。
由于行数可能在<tenant>
和</tenant>
之间变化,因此我不能在grep上使用-A,-B或-C。
任何帮助都会在这里得到解决。
我目前只做-C足够大,所以我至少有所有的信息,但也许一旦长度会更长,我的方法搞砸了。
答案 0 :(得分:2)
awk / grep / sed(正则表达式)不适合您的要求。因为我对你的问题的理解是:
所以,xpath
是正确的方法:
//tenant[something='whatever']
更改something
和whatever
您将获得相应的tenant
元素。
如果您更喜欢使用linux cmd工具,xmllint
就是一个例子:
xmllint --xpath "//tenant[something='whatever']" your.xml
答案 1 :(得分:1)
将GNU awk用于多字符RS和RT:
$ awk -v RS='</tenant>' '/<something>whatever<\/something>/{print $0 RT}' file
<tenant>
<name>bla</name>
<id>1</id>
<something>whatever</something>
</tenant>
<tenant>
<name>foo</name>
<id>55</id>
<something>whatever</something>
</tenant>
答案 2 :(得分:0)
以下pcregrep只有在包含字符串<something>whatever</something>
$ pcregrep -M -o '(?s)<tenant>\n\K.*?<something>whatever<\/something>.*?(?=\n<\/tenant>)' file
<name>bla</name>
<id>1</id>
<something>whatever</something>
<name>foo</name>
<id>55</id>
<something>whatever</something>
使用<tenant>
代码。
$ pcregrep -M -o '(?s)<tenant>\n.*?<something>whatever<\/something>.*?<\/tenant>' file
<tenant>
<name>bla</name>
<id>1</id>
<something>whatever</something>
</tenant>
<tenant>
<name>foo</name>
<id>55</id>
<something>whatever</something>
</tenant>
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed -n '/<tenant>/{:a;N;\|</tenant>|!ba;\|<something>whatever</something>|p}' file