-1

please help me figure out what I am doing wrong.

I have this file called "res.xml"

<sequence type="a"> <transaction> <branchSerial>1</branchSerial> <postingDate>2021-08-02</postingDate> <postingTime>2021-08-06 19:42:49 UTC</postingTime> <step type="a"> <record type="c" label="deviceRecord"> <operation option="V">View</operation> <tableName>DEVICE</tableName> <tableDescription>Device</tableDescription> <rowDescription>[email protected]</rowDescription> </record> </step> </transaction> </sequence> 

I am trying to pull the postingDate and put into a variable. My script:

#!/bin/ksh dbDATE=$(sed -n -e "s/<postingDate>\([0-9]*\)<\/postingDate>/\1/p" res.xml) echo "current DB date: $dbDATE" 

when I run it, I get nothing, just blank.

It is very odd because I have used the same logic elsewhere without problems. Can anybody see what I am missing???

Thank you so much for any help you can provide

4
  • 2
    Your date string contains hyphens as well as digits: [0-9-]*CommentedAug 6, 2021 at 20:04
  • 2
    ... although you should probably be using an XML aware tool such as xmlstarlet sel -t -v '//postingDate' dateRes.xmlCommentedAug 6, 2021 at 20:10
  • @steeldriver thank you so much! I added the '-' and its working proper, you're a life saver.. I would love to use one of the sweet XML tools out there but this on my company's server where we wont be able to download anything external. Thanks again, cheers!
    – Hugobop
    CommentedAug 6, 2021 at 21:25
  • @ShelbyAnne You need to have a word with your managers about what tools you have to work with. If you were working in any other area and you were not given the correct tools to work with, you would be absolutely correct in calling your managers negligent.
    – Kusalananda
    CommentedAug 6, 2021 at 22:00

3 Answers 3

2

The main issue with your sed approach is that you do not allow the date to contain dashes.


To extract the data from the file that you show, you would use an XML-aware parser for the command line.

One example of such a parser is xmlstarlet, which you would use either like this:

dbDATE=$( xmlstarlet sel -t -v '/sequence/transaction/postingDate' res.xml ) 

or, if the node you're looking for the value of is the only such node,

dbDATE=$( xmlstarlet sel -t -v '//postingDate' res.xml ) 

Another XML-aware parser is xq, an XML parser wrapper around the JSON parser jq:

dbDATE=$( xq -r '.sequence.transaction.postingDate' res.xml ) 

All of the above assumes that the sequence node contains only a singletransaction node. Do we want to support multiple transactions (the word "sequence" hints that this may contain a list of transactions), you will also need to decide whether you want to pick the first transaction or specific transaction given some other condition.

Assuming we want the transaction with a branchSerial value of 1. With xmlstarlet:

dbDATE=$( xmlstarlet sel -t -v '/sequence/transaction[branchSerial=1]/postingDate' res.xml ) 

With xq:

dbDATE=$( xq -r '.sequence.transaction[] | select(.branchSerial == "1").postingDate' res.xml ) 
    0

    Lets say you set the .xml output to a variable, you can do the following:

    xmlData=' <sequence type="a"> <transaction> <branchSerial>1</branchSerial> <postingDate>2021-08-02</postingDate> <postingTime>2021-08-06 19:42:49 UTC</postingTime> <step type="a"> <record type="c" label="deviceRecord"> <operation option="V">View</operation> <tableName>DEVICE</tableName> <tableDescription>Device</tableDescription> <rowDescription>[email protected]</rowDescription> </record> </step> </transaction> </sequence> ' date=$(echo "$xmlData" | grep "postingDate" | tr '>' " " | tr '<' " " | awk '{print $2}') 

    Since you said you are pulling it in from a file though, you can even do this:

    date=$(cat res.xml | grep "postingDate" | tr '>' " " | tr '<' " " | awk '{print $2}') 
    2
    • This works for he data as given, but not if there are several transactions with postingDate entries, nor if the postingDate node has attributes.
      – Kusalananda
      CommentedAug 7, 2021 at 6:51
    • I agree. I gave a specific use case since he gave a specific datafile rather than an example of oneCommentedAug 7, 2021 at 18:03
    -2

    works fine with below command

    dbdate=$(awk -F "[<>]" '/postingDate/{print $3}' res.xml) echo -e "current DB date: $dbdate" current DB date: 2021-08-02 
    2
    • Please let me know the reason for downvoteCommentedAug 7, 2021 at 9:18
    • 2
      This worked very well for me thank you! I don't know why someone downvoted. Can you please explain why {print $3} part worked?
      – Hugobop
      CommentedAug 10, 2021 at 16:52

    You must log in to answer this question.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.