我正在尝试使用 jq 将对象 {...} 添加到父对象 [...]。
但以下
parent="[]"
block=$(cat << EOF
{
"block_id": "$block_id",
"block_parent_id": "$block_parent_id",
"current_index": 0,
"child_sum": 0,
"block_cidr": "",
"block_size": "",
"child_cidr": "",
"child_size": "",
"subnets": []
}
EOF
)
jq --arg ITEM "$block" '.+[$ITEM]' <<< "$parent"
给出
[
"{\n\t\"block_id\": \"\",\n\t\"block_parent_id\": \"\",\n\t\"current_index\": 0,\n\t\"child_sum\": 0,\n\t\"block_cidr\": \"\",\n\t\"block_size\": \"\",\n\t\"child_cidr\": \"\",\n\t\"child_size\": \"\",\n\t\"subnets\": []\n}"
]
正如您所看到的,像 \n 和 \t 这样的转义字符是按字面编码的。如何将项目添加到父级 [] 并正确翻译转义字符(例如 \n -> 新行)?
参考https://replit.com/@LoganLee7/jq-add-item-encodes-nt#main.sh
答案1
我找到了答案:
jq --arg ITEM "$block" '.+[$ITEM|fromjson]' <<< "$parent"
或者
jq --argjson ITEM "$block" '.+[$ITEM]' <<< "$parent"
答案2
这个问题有两个方面:
您将 JSON 交给
jq
using--arg
,它需要文本。这意味着jq
会将给定文本 JSON 编码为字符串。当传递的数据是 JSON 文档时,该jq
实用程序有一个单独的选项。--argjson
在最一般的情况下,您不希望将 shell 变量注入到 JSON 文档中而不对其内容进行编码。您可以通过将变量的数据传递给
jq
using--arg
或使用一些其他jo
需要非 JSON 输入并生成 JSON 输出的工具(例如 )来完成此操作。
- 您还可以使用不加引号的方式,如果设置了 shell 选项(或等效的,如)
[]
,这会导致 shell 抱怨。 shell默认设置了shell 选项。failglob
nomatch
zsh
zsh
nomatch
您的问题最好通过使用jq
将数据直接添加到现有文档中来解决:
jq \
--arg block_id "$block_id" \
--arg block_parent_id "$block_parent_id" \
--argjson current_index 0 \
--argjson child_sum 0 \
--arg block_cidr "" \
--arg block_size "" \
--arg child_cidr "" \
--arg child_size "" \
'. += [ $ARGS.named | .subnets = $ARGS.positional ]' \
--args \
<<<"$parent"
在上面的命令中,我创建了一个对象,并$parent
通过使用$ARGS.named
每个普通(标量)键值对将其添加到现有列表中。的值$ARGS.named
是一个对象,其键和值取自--arg
选项及其值。然后我subnets
使用添加数组$ARGS.positional
。该值是--args
命令行上后面的值的数组。该--args
选项必须是命令行上的最后一个选项,并且上面命令中的列表为空。
如果要创建单独添加的对象:
to_add=$(
jq -n \
--arg block_id "$block_id" \
--arg block_parent_id "$block_parent_id" \
--argjson current_index 0 \
--argjson child_sum 0 \
--arg block_cidr "" \
--arg block_size "" \
--arg child_cidr "" \
--arg child_size "" \
'[ $ARGS.named | .subnets = $ARGS.positional ]' \
--args
)
jq --argjson block "$to_add" '. += $block' <<<"$parent"