在上一行中搜索一行中另一个字符串之后的字符串



我达到了我的目标,但它既不优雅也不健壮:

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 进行搜索。

最新更新