2

I have a file with the following contents in an array. I call this FAVORITE_FULL in my Bash Script.

[
    {
        "name": "__SOLOPIANO__ by rautemusik (rm.fm)",
        "url_resolved":"https://rautemusik-de-hz-fal-stream14.radiohost.de/solopiano?ref=radiobrowser&listenerid=31363235323832333936-326130333a343030303a33373a34323a633466653a346366663a666561373a38393431-3533343132-53747265616d436865636b426f742f302e312e30",
        "favicon": "https://i.ibb.co/48KRX7M/solopiano.jpg",
        "tags": "ambient,jazz,smooth lounge,smooth,smooth jazz",
        "countrycode": "DE",
        "language": "english,deutsch german,deutsch,german"
    },
    {
        "name": "- 0 N - Smooth Jazz",
        "url_resolved":"http://0n-jazz.radionetz.de/0n-jazz.aac",
        "favicon": "http://www.0nradio.com/images/favicon/mstile-144x144.png",
        "tags": "ambient,jazz,smooth lounge,smooth,smooth jazz",
        "countrycode": "DE",
        "language": "german"
    },
    ...
]

And during the process, I create a JSON in a file. I call this TEMP_FILE2 in my script.

{
        "name": ".977 Smooth Jazz",
        "url_resolved":"http://19353.live.streamtheworld.com:3690/977_SMOOJAZZ_SC",
        "favicon": "http://977music.com/images/logo.gif",
        "tags": "jazz,smooth jazz",
        "countrycode": "US",
        "language": "english"
    }

Now I want to add TEMP_FILE2 to FAVORITE_FULL. I tried the followings according to this thread.

1.

jq '.[] += ["$TEMP_FILE2"]' "$FAVORITE_FULL" "$TEMP_FILE2"

This returns the following error.

jq: error (at /Users/shinichiokada/.tera/favorite.json:33): object ({"name":"__...) and array (["$TEMP_FIL...) cannot be added
jq: error (at /tmp/tera_favorite2.json:1): Cannot iterate over null (null)
jq --argjson TEMP "$(cat "$TEMP_FILE2")" '.[] += [$TEMP]' "$FAVORITE_FULL"

This returns the following error.

jq: error (at /Users/shinichiokada/.tera/favorite.json:33): object ({"name":"__...) and array ([{"changeuu...) cannot be added

How can I add a JSON in a file to an array in another file?

shin
  • 729
  • 5
  • 15

1 Answers1

8
jq '. += [input]' "$FAVORITE_FULL" "$TEMP_FILE2"

This adds the object in the second file to the array of the first file by adding [input] to the array with +=. The input function reads the next input file and we're using it here to read the contents of $TEMP_FILE2 into an array which is added to the array in $FAVORITE_FULL (an object can't be added as-is to an array with +=, it needs to be put into its own array first).

Alternatively,

jq '[ .[], input ]' "$FAVORITE_FULL" "$TEMP_FILE2"

This expands the array from the first file, and then creates a new array from this with the object from the second file as the last element.

You could also use --slurp or -s:

jq -s '.[0] += [.[1]] | .[0]' "$FAVORITE_FULL" "$TEMP_FILE2"

This reads all input files into an array, with the array of the first file in .[0] and the object to be added in .[1]. We then create an array for the new object using [.[1]] and add it onto the array. At the end we output the updated .[0] array.

With the same sort of variation as in the alternative solution above:

jq -s '[ .[0][], .[1] ]' "$FAVORITE_FULL" "$TEMP_FILE2"

I'm also noting that your attempt with --argjson would have worked with a small tweak:

jq --argjson t "$(cat "$TEMP_FILE2")" '. += [$t]' "$FAVORITE_FULL"

Note the . (an array) in place of your .[] (a set of objects, an expanded array).

Alternatively, with --slurpfile:

jq --slurpfile t "$TEMP_FILE2" '. += $t' "$FAVORITE_FULL"

Note $t instead of [$t] here. When we use slurp mode, the data that is slurped is always put into an array, so $t is an array with the single object from $TEMP_FILE2 in this last example.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936