0

We are logging XML messages to a downstream system in our logs.

I am trying to use sed to extract the XML from the log entry, but not sure exactly how to use it.

This is a typical log entry:

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}]

How could I strip the front and end of the log entry from the XML?

The output from sed for the above line should be:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><canonMessage xmlns="somenamespace">...the message body...</canonMessage>

  • Kindly post the expected output – Praveen Kumar BS Feb 20 '18 at 17:57
  • grep -o '<?xml.*</canonMessage>' /path/to/log should do the trick. – DopeGhoti Feb 20 '18 at 17:58
  • @DopeGhoti can you post that as an answer? – Jose Chavez Feb 20 '18 at 18:01
3

grep -o '<?xml.*</canonMessage>' /path/to/log should do the trick.

The -o option for grep tells it only output data which match the provided regular expression. Happily, you're only talking here about extracting (partial) XML, not parsing it.

  • 1
    Yes this worked for me. For parsing I would use XSLT, which just involves piping the XML output to another process ( – Jose Chavez Feb 20 '18 at 19:18
0

I got the above mentioned output by using below mentioned sed command

sed  "s/.*payload=//g" input.xml | sed "s/,.*//g"

output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><canonMessage xmlns="somenamespace">...the message body...</canonMessage>
0

If you really want to use sed instead of grep, you could have it do a search & replace and only print only if it matched something:

sed -n 's%.*\(<?xml .*</canonMessage>\).*%\1%p' < input

Here we are -not printing lines by default, then do a search-and-replace of the <?xml ...</canonMessage> text; the escaped parenthesis around that text "capture" it into numbered slots. By adding greedy .* regex captures before and after the desired XML text, we can replace the entire line with the saved text in \1 and then print the resulting line.

I used % to separate the search-text and replacement-text because the </canonMessage> has the typical forward-slash separator in it. If you like the forward-slash separator better, you'd just have to escape the one you're trying to match:

sed -n 's/.*\(<?xml .*<\/canonMessage>\).*/\1/p' < input

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.