MUHAHA
MUHAHA

Reputation: 1857

jq create array and append entry to it

I want to produce json file with structure like this:

{
  "data": [
    [
      "Tiger Nixon",
      "Edinburgh"
    ],
    [
      "Garrett Winters",
      "Tokyo"
    ]
  ]
}

Here is my bash script:

list=( http://RESTURL1 http://RESTURL2 )

jq -n .data[] > result.json ## -> (create empty array data)

for p in $list

VAR1=$(curl $p | jq -r .foo ) ## -> (Tiger Nixon)
VAR2=$(curl $p | jq -r .bar ) ## -> (Edinburgh)

cat result.json | jq -n --arg a "$VAR1" --arg b "$VAR2"  .data["$a","$b"] >> results.json ## -> (add Tiger Nixon and Edinburgh to .data array)

done

Script is selfexplaining. Except jq part. I dont know how to handle jq to create json file.

Basically I want to iterate over list of urls, populate 2 variables and push it to results.json file as entry/per iteration.

Thanks

Upvotes: 0

Views: 4433

Answers (3)

Charles Duffy
Charles Duffy

Reputation: 295756

Reusing Glenn's test framework, but calling jq only once for the entire script:

list=( http://RESTURL1 http://RESTURL2 )

declare -A hypothetical_data=(
    [http://RESTURL1]='{"foo":"Tiger Nixon","bar":"Edinburgh"}'
    [http://RESTURL2]='{"foo":"Garrett Winters","bar":"Tokyo"}'
)

for url in "${list[@]}"; do
  echo "${hypothetical_data[$url]}"  # or curl "$url"
done | jq -n '{"data": [inputs | [.foo, .bar]]}'

Upvotes: 4

glenn jackman
glenn jackman

Reputation: 247162

#!/bin/bash

list=( http://RESTURL1 http://RESTURL2 )

declare -A hypothetical_data=(
    [http://RESTURL1]='{"foo":"Tiger Nixon","bar":"Edinburgh"}'
    [http://RESTURL2]='{"foo":"Garrett Winters","bar":"Tokyo"}'
)

# create the seed file
result="result.json"
echo '{"data":[]}' > "$result"

for url in "${list[@]}"; do
    # fetch the data.
    json=${hypothetical_data[$url]}
    # would really do: json=$(curl "$url")

    # extract the name ("foo") and location ("bar") values
    name=$( jq -r '.foo' <<<"$json" )
    location=$( jq -r '.bar' <<<"$json" )

    jq --arg name "$name" \
       --arg loc "$location" \
         '.data += [[$name, $loc]]' "$result" | sponge "$result"

    # "sponge" is in the "moreutils" package that you may have to install. 
    # You can also write that line as:
    #
    # tmp=$(mktemp)
    # jq --arg name "$name" \
    #    --arg loc "$location" \
    #      '.data += [[$name, $loc]]' "$result" > "$tmp" && mv "$tmp" "$result"
    #                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
done

End result:

$ cat result.json
{
  "data": [
    [
      "Tiger Nixon",
      "Edinburgh"
    ],
    [
      "Garrett Winters",
      "Tokyo"
    ]
  ]
}

Upvotes: 3

Andrea Corbellini
Andrea Corbellini

Reputation: 17781

Do you really need to write the file using jq?

list=( http://RESTURL1 http://RESTURL2 )

exec > result.json    

echo '['

for p in "${list[@]}"
    data=$(curl "$p")
    echo "  $(jq -c '[.foo, .bar]' <<< "$data"),"
done

echo ']'

Upvotes: 0

Related Questions