我们将 XML 消息记录到日志中的下游系统。
我正在尝试sed
从日志条目中提取 XML,但不确定如何使用它。
这是一个典型的日志条目:
2018-02-20T10:02:51.395Z|hostname1|user1||Application Name||10062|DEBUG|o.s.i.channel.DirectChannel||postSend (sent=true) on channel 'logger', message: GenericMessage [payload=<?xml version="1.0" encoding="UTF-8" standalone="yes"?><canonMessage xmlns="somenamespace">...the message body...</canonMessage>, headers={quote_format=FpML, id=f572ea65-91dd-a610-7976-5a1e97c16524, quote_message_id=b640bd90-1624-11e8-a904-bd3c0f5af83b_1519120971176, quote_data=Quote Rep, quote_transaction_originator=user1, timestamp=1519120971394}]
如何从 XML 中去除日志条目的前端和结尾?
sed
上述行的输出应该是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><canonMessage xmlns="somenamespace">...the message body...</canonMessage>
答案1
grep -o '<?xml.*</canonMessage>' /path/to/log
应该可以解决问题。
-o
的选项告诉grep
它仅有的输出与提供的正则表达式匹配的数据。幸运的是,你在这里只谈论提取(部分)XML,不是解析它。
答案2
我通过使用下面提到的 sed 命令得到了上面提到的输出
sed "s/.*payload=//g" input.xml | sed "s/,.*//g"
输出
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><canonMessage xmlns="somenamespace">...the message body...</canonMessage>
答案3
如果你真的想要使用 sed 而不是grep,您可以让它进行搜索和替换,并且仅在匹配某些内容时才打印:
sed -n 's%.*\(<?xml .*</canonMessage>\).*%\1%p' < input
这里我们-n
默认打印行,然后对<?xml ...</canonMessage>
文本进行搜索和替换;该文本周围的转义括号将其“捕获”到编号槽中。通过在所需的 XML 文本之前和之后添加贪婪的.*
正则表达式捕获,我们可以用保存的文本替换整行\1
,然后打印结果行。
我曾经%
将搜索文本和替换文本分开,因为</canonMessage>
其中有典型的正斜杠分隔符。如果您更喜欢正斜杠分隔符,则只需转义您要匹配的分隔符即可:
sed -n 's/.*\(<?xml .*<\/canonMessage>\).*/\1/p' < input