【问题标题】:Create JSON file using jq使用 jq 创建 JSON 文件
【发布时间】:2018-01-10 04:03:06
【问题描述】:

我正在尝试通过执行以下命令来创建 JSON 文件:

jq --arg greeting world '{"hello":"$greeting"}' > file.json

这个命令没有任何输入就卡住了。而

jq -n --arg greeting world '{"hello":"$greeting"}' > file.json

没有正确解析。我只是想知道是否真的可以创建一个 JSON 文件。

【问题讨论】:

  • jq -n --arg greeting world '{"hello":$greeting}' > file.json
  • @JeffMercado 据你所知可能有类似'{"hello":$greeting-for-you}'
  • 嗯,它不是有效的 jq 语法,所以它不起作用。我们有一个变量greeting,其字符串值为"world"。您可以使用$greeting 访问该变量值。我不知道你对-for-you 部分的意图是什么,但你可以做很多事情,只要你使用正确的语法来表达它。

标签: json jq


【解决方案1】:

所以你的代码不起作用,因为在双引号内包含了变量,它被视为字符串。这就是为什么它不起作用

正如@Jeff Mercado 指出的解决方案是

jq -n --arg greeting world '{"hello":$greeting}' > file.json

关于名称中的-。这实际上是可能的。但截至目前,这在 jq 的发布版本中不可用。如果你在你的系统上编译 jq 的 master 分支。有一个名为$ARGS.named 的新变量可用于访问信息。

我刚刚编译并检查了下面的命令,它就像一个魅力

./jq -n --arg name-is tarun '{"name": $ARGS.named["name-is"]}'
{
  "name": "tarun"
}

【讨论】:

  • 虽然这可能适用于从命令行传入的参数,但您知道一般变量是否可以使用相同的工具吗?即,是否存在这样的东西:1 as $["some-var"] | $["some-var"] | $VARS.named["some-var"] 我已经有一段时间没有查看源代码或语法了,所以我不知道接下来会发生什么。
  • 就个人而言,我认为这种机制不是很好。这似乎是一种缓解变量名限制的迂回方式。这是一个非问题恕我直言的解决方案。对变量名称有限制是有原因的,以使设计语言和使用它更容易。同样的限制不适用于对象键名,因此这些机制应该存在。
  • @JeffMercado - Tarun 所描述的漏洞可以被视为有朝一日可能会修复的错误!
  • @peak:漏洞,你指的是名字中的破折号吗?我找到了提示添加$ARGS 对象的issue(和PR)。我想接受破折号是一个意想不到的结果。
【解决方案2】:

$ARGS 提供从 jq 命令行访问命名 (--arg name value) 和位置 (--args one two three) 参数,并允许您轻松安全地构建对象。

命名参数:

$ jq -n '{christmas: $ARGS.named}' \
  --arg one 'partridge in a "pear" tree' \
  --arg two 'turtle doves'

{
  "christmas": {
    "one": "partridge in a \"pear\" tree",
    "two": "turtle doves"
  }
}

位置参数:

$ jq -n '{numbers: $ARGS.positional}' --args 1 2 3

{
  "numbers": [
    "1",
    "2",
    "3"
  ]
}

请注意,您可以访问位置数组的各个项目,并且命名参数可以直接作为变量使用:

jq -n '{first: {name: $one, count: $ARGS.positional[0]}, all: $ARGS}' \
  --arg one 'partridge in a "pear" tree' \
  --arg two 'turtle doves' \
  --args 1 2 3

{
  "first": {
    "name": "partridge in a \"pear\" tree",
    "count": "1"
  },
  "all": {
    "positional": [
      "1",
      "2",
      "3"
    ],
    "named": {
      "one": "partridge in a \"pear\" tree",
      "two": "turtle doves"
    }
  }
}

【讨论】:

【解决方案3】:

要补充JeffTarun 已经说过的内容,您可能需要在命令中使用\() 字符串插值语法。例如。

jq -n --arg greeting world '{"hello":"\($greeting)"}'

对我来说这会产生

{
  "hello": "world"
}

关于您对 Jeff 评论的回复,您选择的参数名称必须是有效的 jq 变量名称,因此像 greeting-for-you 这样的 arg 将不起作用,但您可以使用下划线,这样 greeting_for_you 就可以了。或者您可以使用 Tarun 描述的版本。

【讨论】:

  • 这里没有理由使用字符串插值,因为 --arg 保证传递给 jq 的值总是一个字符串。实际上,也不需要“he​​llo”周围的引号。因此写{hello: $greeting} 就可以了。
  • 你是对的——在这个例子中它是不必要的。我在看到Mazzy 的评论后写了这篇文章,认为他们实际上可能想要{"hello":"\($greeting)-for-you"} 之类的东西
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多