25

我正在使用jq从变量值形成 bash 中的 JSON。

了解如何制作普通变量

$ VAR="one two three"
$ jq -n "{var:\"$VAR\"}"
{
  "var": "one two three"
}

但还不能制作数组。我有

$ echo $ARR
one
two
three

并想得到类似的东西

{
  "arr": ["one", "two", "three"]
}

我只设法得到像这样的乱码输出

$ jq -n "{arr: [\"$ARR\"]}"
{
  "arr": [
    "one\ntwo\nthree"
  ]
}

如何以正确的方式形成 JSON 数组?能jq做到吗?

编辑:当只有 jq 1.3 时提出问题。现在,在 jq 1.4 中,可以直接按照我的要求去做,比如 @JeffMercado 和 @peak 建议的,为他们投票。虽然不会撤消对@jbr 答案的接受。

4

6 回答 6

31

在 jq 1.3 及更高版本中,您可以使用--arg VARIABLE VALUE命令行选项:

jq -n --arg v "$VAR" '{"foo": $v}'

即,--arg将变量设置为给定值,以便您可以$varname在 jq 程序中使用,现在您不必在 jq 程序中使用 shell 变量插值。

编辑:从 jq 1.5 起,您可以使用 --argjson 直接传入一个数组,例如

jq -n --argjson v '[1,2,3]' '{"foo": $v}'
于 2014-06-19T06:41:07.420 回答
18

加载变量后,您应该使用split过滤器将该字符串拆分为数组。

$ jq -n --arg inarr "${ARR}" '{ arr: $inarr | split("\n") }'
于 2014-08-04T17:40:47.143 回答
11

该线程中的原始帖子提到了 VAR="一二三"。对于这样一个变量,jq 1.4中一个非常简单的解决方案如下:

$ jq -n -c -M --arg s "$VAR" '{var: ($s|split(" "))}'
{"var":["one","two","three"]}

(这假设是 Linux 或 Mac shell 或类似的,并且适用于 jq 1.4。)

如果分隔符是换行符,请考虑以下打字稿:

$ s=$(printf "a\nb\nc\n")
$ jq -n -c -M --arg var "$s" '{"var": ($var|split("\n"))}'
{"var":["a","b","c"]}

请注意,换行符的 JSON 字符串是"\n"(not "\\n")。

第三种感兴趣的情况是 VAR 是 bash 数组。在这种情况下,使用“${VAR[@]}”传入项目可能是可以接受的,但通常必须记住,“--arg name value”选项仅用于传入字符串。

在 jq>1.4 中,可以使用“env”对象传入导出的 shell 变量,如在线 jq 手册页中所述。

于 2014-11-30T23:51:17.507 回答
7

首先,您必须使用-R来读取原始行,然后您必须使用以下命令来啜饮所有值-s

$ echo -e "one\ntwo\nthree" | jq -R . | jq -s '{"arr": .}'
{
  "arr": [
    "one",
    "two",
    "three"
  ]
}
于 2016-11-08T16:02:14.833 回答
6

这在 jq 1.6 中对我有用:

$ jq -nc '$ARGS.positional' --args 1 2 3
["1","2","3"]

对于这个特定的用例,您可以使用数组并编写:

$ VAR=(one two three)
$ jq -nc '{var: $ARGS.positional}' --args ${VAR[@]}
{"var":["one","two","three"]}

你也可以使用这样的字符串:

$ VAR="one two three"
$ jq -nc '{var: ($ARGS.positional[0] | split(" "))}' --args $VAR
于 2019-02-07T14:50:48.513 回答
4

jq正在做你告诉它做的事情。jq不是生成 JSON 的程序,而是查询它的工具。您对-n交换机所做的只是将其用作漂亮的打印机。因此,如果您希望它打印一个包含“一”、“二”、“三”的数组的对象,那么您必须生成它。

VAR="one two three"
VAR=$(echo $VAR | sed -e 's/\(\w*\)/,"\1"/g' | cut -d , -f 2-)
echo "{var: [$VAR]}"

更新

正如Bryan和其他人在下面提到的那样,确实可以使用 jq 生成 JSON,并且从 1.4 版开始,甚至可以直接执行 OP 要求的操作,例如参见Jeff's answer

于 2014-03-16T09:13:56.287 回答