skip to Main Content

I am having problems parsing a JSON file using jq from a .sh script. When the object contains a space, shell splits it into two. Can i escape the space somehow?

From command line:

echo $(jq '.' ../ext/js/language/languages.json) | jq -c '.[1]'
returns:

{"iso":"en","language":"English","flag":"πŸ‡ΊπŸ‡ΈπŸ‡¬πŸ‡§","exampleText":"don't read"}

which is what i want (languages.json contains an array of such objects)

From shell:

entries=($(jq -c '.[]' ../ext/js/language/languages.json))
echo "[1] ${entries[1]}"
echo "[2] ${entries[2]}"
[1] {"iso":"en","language":"English","flag":"πŸ‡ΊπŸ‡ΈπŸ‡¬πŸ‡§","exampleText":"don't
[2] read"}

2

Answers


  1. Why is my shell script splitting my JSON object in the middle of a string?

    Because unquoted command substitution $(...) is split a space t":"don't read"} into two elements.

    Can i escape the space somehow?

    No, word splitting on unquoted expansion ignores any escapes. Additionally, filename expansion also runs on unquoted expansion. Instead, you have to use a completely different method, where you do not use the result from an unquoted expansion. What code actually to write, depends on the result that you want to get.

    Remember to check your scripts with shellcheck, which helps to protect also against unquoted expansions.

    Login or Signup to reply.
  2. You could convert each item into a JSON-encoded string using @json, and escape that for shell using @sh. Then, On the shell’s side, use declare -a to declare the indexed Bash array.

    unset entries
    declare -a entries="($(
      jq -r '.[] | @json | @sh' ../ext/js/language/languages.json
    ))"
    echo "[1] ${entries[1]}"
    
    [1] {"iso":"en","language":"English","flag":"πŸ‡ΊπŸ‡ΈπŸ‡¬πŸ‡§","exampleText":"don't read"}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search