0

I'm new to bash scripting. I am iterating over a list and want to get the value from a JSON object. I've tried all 3 of these and am getting a jq: 1 compile error

What is the proper syntax?

for key in $KEYS
  echo "ALIASES:" $ALIASES
  # ALIASES: {'a': 'apple', 'b': 'bananna'}

FRUIT=$(echo $ALIASES | jq ."$key" -r)
FRUIT=$(echo $ALIASES | jq .'$key' -r)
FRUIT=$(echo $ALIASES | jq .$key -r)
2
  • It's unclear what the exact values of $ALIASES and $KEYS are. Given the JSON in the code, that should generate a parse error: Invalid numeric literal message, unless the value in $key is not a valid JSON key.
    – Kusalananda
    Oct 28, 2022 at 5:47
  • I may also want to know why you are using a shell loop over the keys of the JSON document instead of performing that loop in jq directly. This would probably only involve a single invocation of jq instead of starting jq once for each key.
    – Kusalananda
    Oct 28, 2022 at 9:05

1 Answer 1

2

The main problem seems to be in your json data because you have:

{'a': 'apple', 'b', 'bananna'}

As far as I know using single quotes is not valid (use double quotes): json format.
The another problem I see is that you have a comma , between 'b' and 'bannana' (I assume you didn't notice that and you typed , instead of :)

So Your json data should be like this:

{"a": "apple", "b": "bananna"}

What is the proper syntax to get a key?

I usually see that the syntax '.key' is more used. However I think you should use any which works. For example, I see in your case that you are using a variable $key to get specific value from a json key. So, you should use something like ".$key" or maybe ."$key", .$key (I'm not sure if these are recommended):

Solution 1

FRUIT=$(echo $ALIASES | jq ".$key" -r)
#or
FRUIT=$(echo $ALIASES | jq ."$key" -r)
#or
FRUIT=$(echo $ALIASES | jq .$key -r)

If you use or want to use single quotes then you will not be able to pass any variable value to jq command. According to man bash:

Enclosing characters in single quotes (') preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash

Therefore If you want to use single quotes to a json value by specifying some key you should use:

FRUIT=$(echo $ALIASES | jq '.somekey' -r)
#e.g.
FRUIT=$(echo $ALIASES | jq '.a' -r)
echo $FRUIT
#Output:
apple

You can check these answers for a better understanding about single quotes and double quotes

Solution 2 (using jq --arg)
I'm not sure why the code above doesn't work for you (using the double quotes). However there is another possible solution to pass variables to jq, you can try:

val="a"
echo $ALIASES | jq --arg key "$val" '.[$key]' -r

As you are using python to get the json then you should use the method json.dumps(your_json), for example:

python3 -c 'import json;aliases = json.load(open("file"));print(json.dumps(aliases))'
5
  • I wouldn't have picked up on that. Thanks Edgar. So I'm going from JSON to python to BASH. The JSON is well formed, and the python I'm doing ALIASES=python3 -c ' import json aliases = json.load(open("file"))] print(aliases) '. In Python, I lose the double quotes. Oct 28, 2022 at 3:52
  • @PartOfTheOhana If you want to change the ' to " you can use these commands: python3 -c 'import json;aliases = json.load(open("file"));print(aliases)' | sed "s/'/\"/g" or python3 -c 'import json;aliases = json.load(open("file"));print(aliases) ' | tr "'" '"'. But you might have problems with the keys-values because if you have something like this: "a": "'app'le", the single quotes in 'app' will be replaced by "app". Oct 28, 2022 at 4:08
  • @PartOfTheOhana I've updated the answer to provide a better solution to get the JSON using the python code. Oct 28, 2022 at 4:17
  • That took care of the double quoting issue. I tried the 3 approaches above to access the value in bash, and in each case I get jq: error: syntax error, unexpected FORMAT, expecting $end (Unix shell quoting issues?) at <top-level>, line 1: Oct 28, 2022 at 4:35
  • @PartOfTheOhana Are you on macOS? I'm using Linux and bash/zsh and that works. I will update the answer to provide another solution! Oct 28, 2022 at 5:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .