0

I am running this simple command

category_ids=`jq '.categories | keys[]' $dictionary_location`

For some reason I have to turn it into an array to iterate properly.

while IFS=';' read -ra cat_ids; do
  for key in "${cat_ids[@]}"; do
    echo 'key:' $key;
  done
done <<< "$category_ids"

If I tried to a loop on category_ids, the word key: would print once and show all the values at once. I'm not sure if I've messed up bash or jq seeing as I have rarely had to touch bash and am brand new to jq.

5
  • 4
    First, category_ids is not an array; it's a regular parameter that contains whatever string is written to standard output by jq. Second, jq can't write anything but a series of bytes to standard output; it certainly cannot interface directly with the shell to "inject" a non-string value into the shell's address space. (Not that a shell array is even a proper data structure; it's more like a handful of syntactic tricks to simulate an array value.) Commented Jun 1, 2021 at 20:32
  • 1
    Shell arrays are meant as another layer of quoting to allow you store arbitrary strings in a collection that doesn't rely on whitespace or any other character to separate the individual strings. It was never really meant to be used as a container data structure. Commented Jun 1, 2021 at 20:34
  • So it looks as though you have a jq program that produces a list of key names, presumably one per line, so what exactly is the problem? There is tons of information on the web and SO about creating bash arrays, so you'll need to be more specific. Btw, I can't help wondering if you wouldn't be better off doing whatever it is you are actually trying to achieve without this step (converting key names to a bash array). Commented Jun 1, 2021 at 20:52
  • The documentation over at stedolan.github.io/jq/manual/#keys,keys_unsorted says it returns an array and this is meant to run in bash so I am not sure how to take the array straight out and use it. I could be using the wrong bash syntax here Commented Jun 1, 2021 at 20:59
  • 2
    @DaveStein The shell doesn't know anything about data types, and certainly not JSON data types. keys produces a JSON array, but the shell has no idea that's what is it, it just sees a stream of bytes (and interprets that as a string, because that's the only data type the shell knows about). Commented Jun 1, 2021 at 22:08

1 Answer 1

1

Why is jq output a string rather than array?

jq writes it output to stdout, a file handle. File handles accept/provide sequences of bytes. This is neither a string nor an array; these concepts are not applicable here.

Backticks substitute the output of the program into the command to execute. Again, this is neither a string nor an array; these concepts are not applicable here.

As for why category_ids isn't an array, the man page for bash says the following:

An indexed array is created automatically if any variable is assigned to using the syntax name[sub‐script]=value. The subscript is treated as an arithmetic expression that must evaluate to a number. To explicitly declare an indexed array, use declare -a name (see SHELL BUILTIN COMMANDS below). declare -a name[subscript] is also accepted; the subscript is ignored.

None of these things were done, so no array was created.


I have to turn it into an array to iterate properly.

Nah, just use a while read loop that reads a line at a time.

while IFS= read -r key; do
  printf 'key: %s\n' "$key"
done <<<"$category_ids"
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.