我有xml格式的日志流(来自名为mytool的促销工具),我需要使它们在一行中看起来可读。我在此节点上没有xml解析工具,因此最终使用了perl和awk。
我设法获得了期望的结果,但希望将管道/ awk / perl的数量减少到最小。
输入流示例:
./mytool
<ALERT>
<Time>2018-10-24T16:03:00.128-05:00</Time>
<Alert>0;2018-10-24T16:02:37.739-05:00;NODE_LOCATION=19;11193;ID=5636122;Temp is on critical range;000;CRITICAL;Recovery=Shutting down the node;100</Alert>
</ALERT>
<ALERT>
<Time>2018-10-24T16:03:03.053-05:00</Time>
<Alert>0;2018-10-24T16:02:40.264-05:00;NODE_LOCATION=17;11293;ID=5636124;Temp is on Major range;000;MAJOR;Recovery=Shutdown the node or it will auto shutdown,processes stopped;99</Alert>
</ALERT>
我想要的结果:
2018-10-24T16:02:37.739-05:00 5636122 Temp is on critical range CRITICAL Shutting down the node
2018-10-24T16:02:40.264-05:00 5636124 Temp is on Major range MAJOR Shutdown the node or it will auto shutdown,processes stopped
我用来获取结果的当前命令:
./mytool | perl -000 -lnpe 's/<.*?>|NODE_LOCATION=|Recovery=|ID=//g' | awk -vRS= '{$1=$1}1' |awk -F';' '{print $2,$$4,$5,$6,$8,$9}'
2018-10-24T16:02:37.739-05:00 5636122 Temp is on critical range CRITICAL Shutting down the node
2018-10-24T16:02:40.264-05:00 5636124 Temp is on Major range MAJOR Shutdown the node or it will auto shutdown,processes stopped
注意:请理解,使用awk perl并不是处理xml的最佳方法,但这是可能的最佳方法,因此必须妥协。
答案 0 :(得分:3)
请尝试以下操作(考虑到您的脚本输出始终与显示的输出处于相同模式)。
your_command | awk -F"[><]" '
/<Time>/{
val=$3
next
}
/<Alert>/{
split($3,array,";")
sub(/.*=/,"",array[5])
sub(/Recovery=/,"",array[9])
print val,array[5],array[6],array[8],array[9]
}'
答案 1 :(得分:2)
mytool | perl -nE 'if(/<Alert>/){s/Recovery=|ID=//g; say join " ",(split/;/)[1,4,5,7,8]}'
如您的示例所示,假设您的XML每行只有一对标记对,那么上述方法将起作用。
答案 2 :(得分:1)
如果需要,您可以在Perl中完成所有操作。避免使用管道连接到awk
。例如:
mytool | perl -nE '
m{<Alert>(.*?)</Alert>} and do {($line = $1) =~ s/NODE_LOCATION=|Recovery=|ID=//g;
@F = split /;/, $line; say join " ", @F[1,3,4,5,6,7,8]}'