1

as described in "Add new element to existing JSON array with jq" I am using this jq form to add elements to a JSON array.

This works fine in the command line. Short minimal version here:

jq '."schemes" += [{ JSON STRING HERE }]' settings.json > settings.json.new

Long, complete version here, I am trying to add a colorscheme to the windows terminal app:

jq '."schemes" += [{
  "name": "Grape",
  "black": "#2d283f",
  "red": "#ed2261",
  "green": "#1fa91b",
  "yellow": "#8ddc20",
  "blue": "#487df4",
  "purple": "#8d35c9",
  "cyan": "#3bdeed",
  "white": "#9e9ea0",
  "brightBlack": "#59516a",
  "brightRed": "#f0729a",
  "brightGreen": "#53aa5e",
  "brightYellow": "#b2dc87",
  "brightBlue": "#a9bcec",
  "brightPurple": "#ad81c2",
  "brightCyan": "#9de3eb",
  "brightWhite": "#a288f7",
  "background": "#171423",
  "foreground": "#9f9fa1",
  "selectionBackground": "#493d70",
  "cursorColor": "#a288f7"
}]' ./settings.json > ./settings.json.new

As said, this works great, and the new colorscheme shows up in Windows Terminal settings. However, when trying to automate this in a shell (bash) script, jq chokes.

# usage is add_colorscheme.sh colorscheme.json
colorscheme=$1
json_content=`cat ${colorscheme}`
json_file="settings.json"
jq '."schemes" += [${json_content}] ${json_file} > ${json_file}.new

I have tried many ways to expand variables, e.g. without braces ($json_content), and have also tried without success with other incantations. For example, using --argjson in the terminal:

json_content=`cat file.json`
echo ${json_content}
{ "name": "Grape", "black": "#2d283f", "red": "#ed2261", "green": "#1fa91b", "yellow": "#8ddc20", "blue": "#487df4", "purple": "#8d35c9", "cyan": "#3bdeed", "white": "#9e9ea0", "brightBlack": "#59516a", "brightRed": "#f0729a", "brightGreen": "#53aa5e", "brightYellow": "#b2dc87", "brightBlue": "#a9bcec", "brightPurple": "#ad81c2", "brightCyan": "#9de3eb", "brightWhite": "#a288f7", "background": "#171423", "foreground": "#9f9fa1", "selectionBackground": "#493d70", "cursorColor": "#a288f7" }
# but jq fails
jq --argjson content ${json_content} '."schemes" += [$content]'
jq: invalid JSON text passed to --argjson
Use jq --help for help with command-line options,
or see the jq manpage, or online docs  at https://jqlang.github.io/jq

or --arg

jq -n --arg content ${json_content} '."schemes" += [env.content]' settings.json
jq: error: syntax error, unexpected ':', expecting end of file (Unix shell quoting issues?) at <top-level>, line 1:
"name":
jq: 1 compile error

I have read a number of other posts like this one, on the topic of jq and variable expansions, but not sure how to even try here strings when I can't even get --arg nor --argjson to work.

I have tried exchanging -n --argjson to --argjson foo bar -n to no avail. I have even read the manpage! There's nothing special about --argjson there that I can see.

What am I doing wrong? Thanks for any help!

My system and context: Ubuntu 24.04.2 LTS, WSL2 jq: v1.7

colorscheme.json:

{
  "name": "Grape",
  "black": "#2d283f",
  "red": "#ed2261",
  "green": "#1fa91b",
  "yellow": "#8ddc20",
  "blue": "#487df4",
  "purple": "#8d35c9",
  "cyan": "#3bdeed",
  "white": "#9e9ea0",
  "brightBlack": "#59516a",
  "brightRed": "#f0729a",
  "brightGreen": "#53aa5e",
  "brightYellow": "#b2dc87",
  "brightBlue": "#a9bcec",
  "brightPurple": "#ad81c2",
  "brightCyan": "#9de3eb",
  "brightWhite": "#a288f7",
  "background": "#171423",
  "foreground": "#9f9fa1",
  "selectionBackground": "#493d70",
  "cursorColor": "#a288f7"
}

settings.json:

{
    "$help": "https://aka.ms/terminal-documentation",
    "$schema": "https://aka.ms/terminal-profiles-schema",
    "language": "en-US",
    "themes": [],
    "schemes": []
}
2
  • 1
    In bash, single quotes block variable expansion. You might need something like jq ".\"schemes\" += [${json_content}] ${json_file}" > ${json_file}.new to get your variables expanded in the jq query. Commented Jul 23 at 3:16
  • Great, thanks! that was it, got my brain exhausted it seems, all makes complete sense now. Commented Jul 23 at 19:14

1 Answer 1

2

Try this instead:

jq '.schemes += [inputs]' "$json_file" "$@" >"$json_file.new"
Sign up to request clarification or add additional context in comments.

3 Comments

not sure if I understand your proposed solution correctly, I'm replacing $@ with the variable containing the JSON string, but it gives an error: jq '.schemes += [inputs]' "${settings_file}" "${json_content}" > "${settings_file}.new" jq: error: could not open file { "name": "colorschemeName", "black": "#2d283f", ... File name too long. Seems like this way of adding contents after the json file is being treated as a filename?
Leave it as is and it'll work. $@ is the list of arguments your script is called with.
Oh! yes, it works, didn't know about $@ in bash. seems like in my case gives the same result as $1 because I'm only specifying one additional json file containing a single colorscheme to add. Works beautifully now, thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.