我有一个像这样的 JSON 文件:
{
"name" : "Allow",
"source" : [ "*" ,"0.0.0.0"]
}
我需要解析这个 JSON,以便 JSON 中的字符串数组可以转换为“空格分隔的字符串”。我稍后需要将这些变量提供给另一个函数,如下所示:
local file="file-name"
while read val; do
local name
local source
name=$(jq --raw-output '.name' <<< ${val})
source=$(jq --raw-output '.source' <<< ${val})
__test "${name}" "${source}"
done < <(cat ${file} | jq -rc '.[]')
所以,我基本上需要将源更改为字符串并传递它,而不是字符串列表。
答案1
join(" ")
通常,可以使用in将数组的元素转换为单个空格分隔的字符串jq
。在您的情况下,.source
可以使用 将该数组转换为空格分隔的字符串.source | join(" ")
。
我假设您的输入文档包含您在问题中显示的类型的对象数组。
jq
不要在每次迭代中多次调用,而是考虑使用jq
将数据转换为可用作单个流的形式:
jq -r '.[] | [ .name, (.source | join(" ")) ] | @tsv' file.json |
while IFS=$'\t' read -r name source; do
__test "$name" "$source"
done
这为循环提供了两个制表符分隔的字段。第一个字段只是.name
JSON 文档中的值,而第二个字段是通过连接数组中的元素而成的空格分隔字符串.source
。使用join()
in将数组元素连接成单个字符串,并通过提供数组jq
来生成制表符分隔的输出。@tsv
如果你勇敢的话,你甚至可以使用
eval "$( jq -r '.[] | [ "__test", .name, (.source | join(" ")) ] | @sh' file.json )"
这用于jq
实际创建您要执行的 shell 命令。然后调用 shell 得到这个脚本作为字符串并使用 运行它eval
。在jq
表达式中,@sh
用于为命令名称及其参数提供正确的引用。这里的表达式jq
需要问题中所示类型的对象数组。