【问题标题】:jq command throws error "cannot iterate over string" whenjq 命令抛出错误“无法迭代字符串”时
【发布时间】:2019-11-02 15:36:34
【问题描述】:

我正在编写一个 bash 脚本,利用 jq 过滤给定一些 bash 变量的 JSON 条目,并将每个条目中的一些键值返回到一个制表符分隔的文件中。我认为该命令的前几行还可以,但我认为第 4 行导致了问题。我已经尝试将第 4 行中的每个条目通过管道连接到 tostring 但无济于事。

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

JSON 示例条目:

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

在这些文件中,文件中的整个文本没有括号。

给定错误:

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

我需要以某种特殊方式处理“.ts”吗?

【问题讨论】:

  • 仅供参考,出于充分的理由,不推荐使用反引号命令替换。运行起来好多了info=$(jq -r ...&lt;"$FILE")
  • 更重要的是,当前输入不是有效的 JSON;它在} 之前有一个,,因此无法完全按照给定的方式进行测试。

标签: bash jq


【解决方案1】:

这段代码在第 3 行之前 long 被破坏了。

  • 如果没有外部数组或对象,则不能使用.[]
  • 如果您的数据类型是对象而不是列表,则在其上使用 map() 会丢弃数据(具体而言,它会丢弃键,只留下值)。

...所以,.[] 迭代对象中的 ,然后 map() 尝试迭代每个值,就好像它本身是一个可迭代对象一样不是......因此你的错误。


为了移除损坏的部分而删减的版本可能如下所示:

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

...效果很好。

【讨论】:

    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2021-06-03
    • 2021-04-27
    • 2021-09-30
    • 2020-01-06
    • 1970-01-01
    • 2015-03-28
    • 2019-09-14
    相关资源
    最近更新 更多