eazypower
eazypower

Reputation: 11

jq command throws error "cannot iterate over string" when

I am writing a bash script utilizing jq to filter out JSON entries given some bash variables and return some of the key values from each entry into a tab-delimited file. I think the first few lines of this command are okay, but the 4th line I think is causing the problem. I have tried piping each entry in line 4 to tostring but to no avail.

info=`cat $FILE | jq -r \
    ' .[] \
    | map(select(.host| contains(env.A))) \
    | [."ip.A",."ts",."ip.B"] \
    | @tsv'`

JSON example entry:

{
  "ts": "2019-06-19T00:00:00.000000Z",
  "ip.A": "0.0.0.0",
  "ip.B": "0.0.0.0",
  "host": "www.google.com",
}

In these files, there are no brackets surrounding the entire text within the file.

Error Given:

jq: error (at <stdin>:0): Cannot iterate over string ("2019-06-18...)

Do I need to handle ".ts" in some special way?

Upvotes: 1

Views: 4928

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295500

This code is broken long before the 3rd line.

  • If there isn't an outer array or object, you can't use .[].
  • If your data type is an object and not a list, using map() on it throws away data (specifically, it discards the keys, leaving only the values).

...so, .[] iterates over the values in your object, and then map() tries to iterate over each of those values as if it was an iterable object itself, which it's not... hence your error.


A version cut down to remove the broken parts might look like:

a="google.com" jq -r '
if (.host | contains(env.a)) then
  [."ip.A",."ts",."ip.B"] | @tsv
else
  empty
end
' <<'EOF'
{
  "ts": "2019-06-19T00:00:00.000000Z",
  "ip.A": "0.0.0.0",
  "ip.B": "0.0.0.0",
  "host": "www.google.com"
}
EOF

...which works fine.

Upvotes: 3

Related Questions