[SOLVED] How to interpolate several values contained in a variable into a json string

Issue

This Content is from Stack Overflow. Question asked by codependent

I have a parsed variable obtained after parsing some text:

parsed=$(echo "PA-232 message1 GX-1234 message2 PER-10 message3" | grep -Eo '[A-Z]+-[0-9]+')

parsed contains a bunch of ids:

echo $parsed
PA-232
GX-1234
PER-10

The next thing I have to do in my script is generate a json text and invoke an API with it:

The json text should be

"{"tasks": [{"taskId": "PA-232"}, {"taskId": "GX-1234"}, {"taskId": "PER-10"}], "projectId": "$CI_PROJECT_ID" }"

Notice CI_PROJECT_ID is an envvar that I also have to send, thats why I needed to use double quotes and escape them.

And it would be called with curl:

curl -X POST -H 'Content-Type:application/json' -k -u $CLIENT_ID:$CLIENT_SECRET 'https://somewhere.com/api/tasks' -d "{"tasks": [{"taskId": "PA-232"}, {"taskId": "GX-1234"}, {"taskId": "PER-10"}], "projectId": "$CI_PROJECT_ID"}"

The question is how can I generate a json string like the one shown above from the parsed variable and the additional envvar?



Solution

How about doing it with jq?

CI_PROJECT_ID='I want this " to be escaped automatically'

echo 'PA-232 message1 GX-1234 message2 PER-10 message3' |

jq -R --arg ciProjectId "$CI_PROJECT_ID" '
    {
        tasks: [
            capture( "(?<taskId>[[:upper:]]+-[[:digit:]]+)"; "g" )
        ],
        projectId: $ciProjectId
    }
'
{
  "tasks": [
    {
      "taskiD": "PA-232"
    },
    {
      "taskiD": "GX-1234"
    },
    {
      "taskiD": "PER-10"
    }
  ],
  "projectId": "I want this \" to be escaped automatically"
}

note: you can use jq -c ... for outputting a compact JSON


And here’s a solution without jq that doesn’t escape the characters in the strings so it might generate invalid JSON:

CI_PROJECT_ID='no escaping needed'

tasks_jsonArr=$(
    echo "PA-232 message1 GX-1234 message2 PER-10 message3" |
    grep -Eo '[A-Z]+-[0-9]+' |
    sed 's/.*/{ "taskiD": "&" }/' |
    paste -sd ',' |
    sed 's/.*/[ & ]/'
)

curl -k 'https://somewhere.com/api/tasks' \
     -X POST \
     -H 'Content-Type:application/json' \
     -u "$CLIENT_ID:$CLIENT_SECRET" \
     -d "{\"tasks\": $tasks_jsonArr, \"projectId\": \"$CI_PROJECT_ID\"}"

N.B. For JSON-escaping strings with standard tools, take a look at function json_stringify in awk


This Question was asked in StackOverflow by codependent and Answered by Fravadona It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?