我达到了我的目标,但它既不优雅也不健壮:
Port=`grep -A5 "web gui" $Conf|awk -F[:<] \
'/address/{print $3}'`
$Conf
是我必须解析的xml文件,通过搜索Port
号,我可以与这台机器/软件进行通信。web gui
字符串在文件中仅出现一次。如您所见,address
显示在web
标记之前、之后和之间。她的位置以及其他行的数量可能会在标签内有所不同。我的代码很弱,因为它依赖于 grp 的 -A5。我想我可以增加它,但我不知道如何将 EOF 指定为 grep,然后用...;exit;}
结束 awk 操作。我不确定,因为我不知道它是否会像grep -m1
一样工作. 我认为肯定有一些单行最好和更短的尴尬。我首先想到使用带有 RS=" 的 awk 或这里的一些特殊字符,意思是 EOF 将文件视为一行,然后使用 FS=["web","address"],但我卡住了。
....
<address>auto</address>
<idle>false</idle>
<someKey>false</someKey>
<otherkey>0</otherkey>
<maxSpeed>0</maxSpeed>
<maxHeat>0</maxHeat>
</machine>
<web gui="on" tls="on" log="off">
<user>****************</user>
<address>127.0.0.1:1234</address>
<password>***************</password>
<key>*********************</key>
<skin>turquoise</skin>
</web>
<OtherTag></OtherTag>
<options>
<Listenaddress>https://someHost.net</Listenaddress>
...
欢迎任何帮助 谢谢
您可以使用sed
的范围功能
sed -rn '
/<web gui=.*>/,/</web>/{
/<address>/s/^[^:]+:([[:digit:]]+).*$/1/p
}' "$Conf"
您可以使用awk
的范围功能
awk -F'[:<]' '
/<web gui=.*>/,/</web>/{
if($0~/address/){print $3}
}' ./input
概念验证
$ sed -rn '/<web gui=.*>/,/</web>/{/<address>/s/^[^:]+:([[:digit:]]+).*$/1/p}' ./input
1234
$ awk -F'[:<]' '/<web gui=.*>/,/</web>/{if($0~/address/){print $3}}' ./input
1234
使用正则表达式解析 XML 是错误的工具。您可能会让它在有限数量的测试用例上运行,但总有人能够想出一种编写破坏代码的 XML 的方法。(这是基于XML语法是递归的事实的理论原因。
使用正确的 XML 分析器分析 XML,并使用 XPath 进行搜索。