msherm
msherm

Reputation: 19

Bash Script Project - Parse JSON and construct cURL POST of XML within loop

Looking for some advice on the direction I should take my project as I'm very new to scripting. My objectives are as follows:

Using cURL to get JSON data, parse a particular object value. I was intending to use jq to parse the JSON and then store the results as a variable.

Here is what I have to started with: SAMPLE JSON -

{
    "href": "http://localhost:8080//profiles",
    "Profiles": [
        {
            "href": "http://localhost:8080/profiles/myprofile",
            "id": "myprofile",
            "isRecording": false
        },
        {
            "href": "http://localhost:8080/profiles/yourprofile",
            "id": "yourprofile",
            "isRecording": false
        }
    ]
}

BASH SCRIPT -

#!/bin/bash

read -p "Please enter downtime name (and press Enter): " downtimename
read -p "Please enter timestart:" timeStart
read -p "Please enter time duration (in minutes): " durationMinutes

#!/bin/bash
PROFILE="$(curl --user admin:admin -k -X GET https://xxx.xx.xx.xxx:8080/profiles.json | jq '.Profiles[].id')"  
echo "$PROFILE"

RETURNS - "myprofile" "yourprofile"

Next I need to construct 1 or more cURL POST of xml data (example below) Each post will be a single curl post of the xml, for each line in the above echo "$PROFILE". I’m thinking this will be a for loop? What I'm struggling with is how to read each value/line from "$PROFILE" and utilize a for loop to post xml while replacing ${profile] in the below curl URL, for each result above.

curl -X POST https://xxx.xx.xx.xxx:8080/testprofiles/${profile}/time/${downtimename} --data-urlencode xml="<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<time>
    <gametime>
    2016-11-23T05:30:00+02:00
        <start>${timeStart}</start>
        <duration unit="MINUTES">${durationMinutes}</duration>
    </gametime>
</time>" -H 'Accept: application/xml' \ -H 'Content-Type: application/xml' -u admin:admin

Thank you in advance for the help

Upvotes: 0

Views: 1079

Answers (1)

Ruslan Osmanov
Ruslan Osmanov

Reputation: 21492

Strings and quotes

The XML string you pass to --data-urlencode is interpreted without double quotes:

<?xml version=1.0 encoding=UTF-8 standalone=yes?>
<time>
    <gametime>
    2016-11-23T05:30:00+02:00
        <start>${timeStart}</start>
        <duration unit=MINUTES>${durationMinutes}</duration>
    </gametime>
</time>

Double quotes are the shell syntax elements that influence parsing. They are removed before the command is called. Prepend a backslash to a double quote, if you want its literal value in the string, e.g. "version=\"1.0\"".

However, here documents are more convenient in most cases:

xml=$(cat <<XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<time>
  <gametime>
    2016-11-23T05:30:00+02:00
    <start>${timeStart}</start>
    <duration unit="MINUTES">${durationMinutes}</duration>
  </gametime>
</time>
XML
)

jq output

Use --raw-output option to skip the JSON formatting. (In particular, string values are wrapped with double quotes by default.).

Turn off color output with --monochrome-output option. With this option, jq will not print the ASCII escape codes.

Although not necessary, I recommend turning off the output buffering with --unbuffered option. With this option, jq will flush the output buffer after each JSON object is printed.

Reading jq output line-by-line

You don't need to store the output of jq command into a variable. It is possible to process the lines on-the-fly using a pipe:

curl --user admin:admin -k -X GET https://xxx.xx.xx.xxx:8080/profiles.json | \
  jq --monochrome-output --unbuffered --raw-output \
    '.Profiles[].id' | while read profile
  do
    echo "Processing profile $profile"
    url="https://xxx.xx.xx.xxx:8080/testprofiles/${profile}/time/${downtimename}"
    curl -X POST "$url" \
      --data-urlencode "xml=$xml" \
      -H 'Accept: application/xml' \
      -H 'Content-Type: application/xml' \
      -u admin:admin
  done

Upvotes: 2

Related Questions