【问题标题】:jq produces `is not defined at <top-level>` errorjq 产生 `is not defined at <top-level>` 错误
【发布时间】:2021-08-30 23:36:30
【问题描述】:

我在像这样调用 jq 时看到 is not defined at &lt;top-level&gt;:

jq ".Changes[0].ResourceRecordSet.Name = word-is-here.domain.com" someFile.json

对于替换的第二侧中由破折号分隔的每个单词,该错误都会重复。完整的错误就像

jq: error: word/0 is not defined at <top-level>, line 1:
.Changes[0].ResourceRecordSet.Name = word-is-here.domain.com

我尝试过以多种不同的方式转义引号,但这并没有帮助。 (我的意思是在做“'”''奇怪的事情,我还在学习 bash,所以我只是在墙上乱扔东西直到它粘住)

编辑: 所以我试图在 bash 脚本中运行它,= 符号的两侧都是变量,例如 jq --arg value "$value" --arg key "$key" '$key = $value' "$path"(我在建议后尝试过)

并得到错误: 路径表达式无效,结果为“.Changes[0].ResourceRecor...

我使用的json是这样的:

{
  "Changes": [
    {
      "Action": "do something",
      "ResourceRecordSet": {
        "Name": "some name here to replace",
         ...
      }
    }
  ]
}

【问题讨论】:

  • 您能否提供一部分 json 以便我们重现该问题?
  • 今后,请尽可能遵循minimal reproducible example 准则。谢谢。
  • @AntonioPetricca 我已经用 json 的一部分更新了这个问题,并详细说明了我在尝试不同的东西(即使用 args)时遇到的其他错误

标签: bash macos zsh jq


【解决方案1】:
jq '.Changes[0].ResourceRecordSet.Name = "word-is-here.domain.com"' file.json

引用您分配的字符串。或者通过参数将其传递给 jq:

jq --arg foo 'words-here' '.Changes[0].ResourceRecordSet.Name = $foo' file.json

为了将路径传递给您想要作为参数的键,https://github.com/stedolan/jq/issues/1493 的建议可能有效:

jq --argjson path '["Changes",0,"ResourceRecordSet","Name"]' \
  --arg val 'word-is-here.domain.com' \
  'getpath($path) = $val' file.json

【讨论】:

  • 我刚刚尝试过,它通过 cmd 行运行,但是当我在脚本中运行它时,如:jq --arg value "$value" --arg key "$key" '$key = $value' "$path"我收到此错误“无效的路径表达式与结果”.Changes[0].ResourceRecor ...”
  • 太棒了,所以最后对我有用的是你的最后一行,但我作为 arg 传入的 foo 周围没有引号。即 jq --argjson path '["Changes",0,"ResourceRecordSet","Name"]' --arg foo "hello-world-blah" 'getpath($path) = foo' file.json
  • @capa_matrix - 您第一次尝试(在第一条评论中)的问题是您使用了--arg key 而不是--argjson key。您希望 key 被理解为 JSON 数组,而不是 JSON 字符串。
【解决方案2】:

这里的问题(或至少是明显的问题)显然是字符串:word-is-here.domain.com,因为 jq 将破折号(“-”)解释为操作(“减号”)。

很遗憾,由于您没有给我们太多线索,因此尚不完全清楚具体需要更改哪些内容,但合理的猜测是word-is-here.domain.com 旨在作为固定字符串。如果是这样,您必须将其呈现为 JSON 字符串。所以在 bash 或类似 bash 的环境中,你可以这样写:

jq '.Changes[0].ResourceRecordSet.Name = "word-is-here.domain.com"' someFile.json

通过 shell 变量指定 LHS 路径

如果 LHS 路径必须由 shell 变量指定,则应尽可能将其作为 JSON 数组传入,例如使用--argjson 命令行选项;然后可以使用setpath($path; $value) 形式的表达式来更新路径。

如果出于某种原因,首选允许将 LHS 指定为 jq 路径的解决方案,则可以使用 shell 字符串插值,但与任何此类插值一样,这应该小心。

【讨论】:

  • 不幸的是,我在等式的两边都使用了变量,我已经用这些细节更新了问题,并感谢您向我指出该页面
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-09
  • 2020-11-30
  • 2017-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多