Clint5047
Clint5047

Reputation: 3

jq: use variable to identify an inner object key to append to

I've been researching this for a bit and I've seen answers that have gotten me closer to solving this, but nothing that actually gets me all the way there.

I have the following JSON file:

{
  "applications": {
    "app1": [
      {
        "id": "1",
        "filename": "install_latest_app.pkg",
        "version": "1.2.3",
        "date": "20190903"
      },
      {
        "id": "2",
        "filename": "install_latest_app.pkg",
        "version": "1.2.4",
        "date": "20190904"
      },
      {
        "id": "3",
        "filename": "install_latest_app.pkg",
        "version": "1.2.5",
        "date": "20190905"
      }
    ]
  }
}

I am trying to use jq in a Bash script to dynamically add entries to this file under the specific "app". In my example there's only one "app" defined (app1) but in a real world scenario there would be more.

#!/bin/bash

title="app1"
filename="install_latest_app.pkg"
version="1.2.6"
date="20190906"
id="6"

jq --arg title "$title" \
--arg filename "$filename" \
--arg version "$version" \
--arg date "$date" \
--arg id "$id" \
'.applications.$title += [{"id": $id, "filename": $filename, "version": $version, "date": $date}]' data.json >> data.json

when trying to run this, I get a compile error.

jq: error: syntax error, unexpected '$', expecting FORMAT or QQSTRING_START (Unix shell quoting issues?) at <top-level>, line 1:
.applications.$title += [{"id": $id, "filename": $filename, "version": $version, "date": $date}]

Same when running it in ways like .applications.[$title] or (.applications.[$title]) (all based on other discussions).

If I do something like .applications | .[$title] |= ... I get a lot closer as it actually returns the JSON with the correct entries, however it doesn't add it to the current "app1", instead adding a new entry for "app1". I would be fine overwriting the entire file every time with the added entry, but I am struggling to get it to print the entire JSON + the new entry. Any help or ideas would be appreciated!

Upvotes: 0

Views: 547

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295766

Instead of .applications.$title or .applications.[$title], use .applications[$title], as in:

jq --arg title "$title" \
   --arg filename "$filename" \
   --arg version "$version" \
   --arg date "$date" \
   --arg id "$id" '
  .applications[$title] += [{$id, $filename, $version, $date}]'

...and output is correctly:

{
  "applications": {
    "app1": [
      {
        "id": "1",
        "filename": "install_latest_app.pkg",
        "version": "1.2.3",
        "date": "20190903"
      },
      {
        "id": "2",
        "filename": "install_latest_app.pkg",
        "version": "1.2.4",
        "date": "20190904"
      },
      {
        "id": "3",
        "filename": "install_latest_app.pkg",
        "version": "1.2.5",
        "date": "20190905"
      },
      {
        "id": "6",
        "filename": "install_latest_app.pkg",
        "version": "1.2.6",
        "date": "20190906"
      }
    ]
  }
}

Upvotes: 1

Related Questions