0

I have a loop where I'm creating a json structure using jq. I create individual json structures with the following.

jq -n \
  --arg name $myname \
  --arg subject $mysubject \
  --arg version "1" \
  '{name: $name, subject: $subject, version: $version}'

But I want to concatenate each structure in to an array, like:

[
    {
      "name": "name1",
      "subject": "subj1",
      "version": "1"
    },
    {
      "name": "name2",
      "subject": "subj2",
      "version": "1"
    }
]

I'm trying something like this with pipes, but the array doesn't get populated.

$myarray=$myarray jq -n \
  --arg name $myname \
  --arg subject $mysubject \
  --arg version "1" \
  '{name: $name, subject: $subject, version: $version}'
Stealth Rabbi
  • 10,156
  • 22
  • 100
  • 176
  • 1
    Quotes matter. `--arg name "$myname"`, `--arg subject "$mysubject"`. By contrast, you _don't_ need quotes around the `1` in `--arg version 1` (they don't hurt anything, but they don't help you at all either). Otherwise names or subjects with whitespace will misbehave. – Charles Duffy Mar 10 '21 at 18:24
  • Beyond that, your code isn't _trying_ to change `myarray`. Just like when you store any other command's output into a variable, you need to use a command substitution; we have lots of non-jq-specific duplicates on that. – Charles Duffy Mar 10 '21 at 18:25
  • ...f/e, [How do I set a variable to the output of a command in bash?](https://stackoverflow.com/questions/4651437/how-do-i-set-a-variable-to-the-output-of-a-command-in-bash) -- `var=$(yourcommand)`; the `$(...)` is critical. – Charles Duffy Mar 10 '21 at 18:26
  • Here is an example that I use in many of my scripts: `smtpHost=$(jq -r '.smtp.host' settings.json)` – L. Ouellet Mar 10 '21 at 18:27
  • Mind, I wouldn't advise calling jq once per item at all -- that's wildly inefficient. Why not let jq parse your whole data feed all at once? Generate a single list of tab-separated items, one item per line, and tell jq to parse your tab-separated lines into a JSON list; there you are. – Charles Duffy Mar 10 '21 at 18:27
  • @CharlesDuffy I'm reading a JSON schema file, manipulating it, and then creating a new JSON structure with other attributes. I'm changing each "ref" (which I've already done) and then trying to create a JSON array for each of those refs in to a JSON array with the key "references". https://docs.confluent.io/platform/current/schema-registry/develop/api.html#post--subjects-(string-%20subject)-versions – Stealth Rabbi Mar 10 '21 at 18:32
  • Hmm. Probably still possible to do it dynamically using code only written in jq -- it's a surprisingly powerful language -- but the details certainly go outside of what falls into reasonable-comment scope. – Charles Duffy Mar 10 '21 at 18:34
  • ...as a quick pointer should you try, though: `{ "\($key)": $value }` will let you dynamically create a dictionary with a chosen key and value (which can be merged with other dictionaries constructing other keys and values, f/e, if you're doing this in a loop). Those can come from anywhere -- you can use `.key` and `.value` instead, for example. – Charles Duffy Mar 10 '21 at 18:37
  • ...similarly, there's no reason you couldn't have your input form to jq be `key1=value1 key2=value2` per line, and have your jq code be responsible for parsing those items out and creating a dictionary per line of input. – Charles Duffy Mar 10 '21 at 18:39

0 Answers0