jq&bash:从变量中生成JSON数组

And*_*tov 20 arrays bash json jq

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

有如何制作纯变量

$ VAR="one two three"
$ jq -n "{var:\"$VAR\"}"
{
  "var": "one two three"
}
Run Code Online (Sandbox Code Playgroud)

但是还不能制作阵列.我有

$ echo $ARR
one
two
three
Run Code Online (Sandbox Code Playgroud)

并希望获得类似的东西

{
  "arr": ["one", "two", "three"]
}
Run Code Online (Sandbox Code Playgroud)

我只是设法得到乱码输出

$ jq -n "{arr: [\"$ARR\"]}"
{
  "arr": [
    "one\ntwo\nthree"
  ]
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:当只有jq 1.3时问的问题.现在,在jq 1.4中,我可以直接按照我要求的那样做,比如@JeffMercado和@peak建议,为他们提供支持.但是不会撤消对@jbr的回答的接受.

小智 24

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

jq -n --arg v "$VAR" '{"foo": $v}'
Run Code Online (Sandbox Code Playgroud)

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

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

jq -n --argjson v '[1,2,3]' '{"foo": $v}'
Run Code Online (Sandbox Code Playgroud)


Jef*_*ado 14

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

$ jq -n --arg inarr "${ARR}" '{ arr: $inarr | split("\n") }'
Run Code Online (Sandbox Code Playgroud)

  • 需要jq 1.4 (3认同)

ash*_*own 11

这在 jq 1.6 中对我有用:

$ jq -nc '$ARGS.positional' --args 1 2 3
["1","2","3"]
Run Code Online (Sandbox Code Playgroud)

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

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

您还可以使用这样的字符串:

$ VAR="one two three"
$ jq -nc '{var: ($ARGS.positional[0] | split(" "))}' --args $VAR
Run Code Online (Sandbox Code Playgroud)


pea*_*eak 7

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

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

(这假设是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"]}
Run Code Online (Sandbox Code Playgroud)

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

第三个感兴趣的案例是VAR是一个bash数组.在这种情况下,使用"$ {VAR [@]}"传递项目是可以接受的,但一般来说,必须记住"--arg name value"选项仅用于传入字符串.

在jq> 1.4中,可以使用"env"对象传递导出的shell变量,如在线jq手册页中所述.


cev*_*ing 6

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

$ echo -e "one\ntwo\nthree" | jq -R . | jq -s '{"arr": .}'
{
  "arr": [
    "one",
    "two",
    "three"
  ]
}
Run Code Online (Sandbox Code Playgroud)


jbr*_*jbr 5

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

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

更新

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

  • 这只适用于 gnu `sed`。我建议将第二行替换为 `VAR=$(printf '"%s"\n' $VAR|paste -sd, -)`。 (2认同)
  • jq 是生成 JSON 的绝佳方法,特别是当您想要写入 JSON 的值中可能包含任何特殊字符(例如“)时 (2认同)