我有以下xml。我需要将IP地址,协议和端口提取到具有相应列名的CSV文件中。
<rule family="ipv4">
<source address="10.XXX.XX.XX"/>
<port protocol="tcp" port="22"/>
<log prefix="ber_" level="warning">
<limit value="1/m"/>
</log>
<accept/>
</rule>
<rule family="ipv4">
<source address="10.XXX.XX.XXX"/>
<port protocol="udp" port="1025"/>
<log prefix="ber_" level="warning">
<limit value="1/m"/>
</log>
<accept/>
我可以使用grep或sed grep IP地址或端口grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
但是我需要它作为CSV文件中的列。
IPAddress协议端口。实现这一目标的最佳方法是什么?
答案 0 :(得分:1)
不要'使用正则表达式来解析html / xml,而是使用真正的解析器(使用xpath):
<root>
<rule family="ipv4">
<source address="10.XXX.XX.XX"/>
<port protocol="tcp" port="22"/>
<log prefix="ber_" level="warning">
<limit value="1/m"/>
</log>
</rule>
<rule family="ipv4">
<source address="10.XXX.XX.XXX"/>
<port protocol="udp" port="1025"/>
<log prefix="ber_" level="warning">
<limit value="1/m"/>
</log>
</rule>
</root>
xmlstarlet sel -t -v '//source/@address | //port/@protocol | //port/@port' file |
perl -pe '$. % 3 != 0 && s/\n/,/g;END{print "\n"}'
10.XXX.XX.XX,tcp,22
10.XXX.XX.XXX,udp,1025
根据编译理论,无法使用基于finite state machine的正则表达式解析HTML。由于HTML的层次结构,您需要使用pushdown automaton并使用LALR等工具操作YACC语法。
您可以使用以下其中一项:
saxon-lint(我自己的项目)
答案 1 :(得分:0)
缺少xml工具,这是一个脆弱的awk
解决方案
1$ awk -v RS='</rule>' '
{for(i=1;i<=NF;i++)
if($i~/^(address|protocol|port)/)
{split($i,a,"\""); printf "%s", a[2] (++c%3?FS:ORS)}}' file
10.XXX.XX.XX tcp 22
10.XXX.XX.XXX udp 1025