使用 jq 将对象字符串添加到数组不会翻译转义字符

使用 jq 将对象字符串添加到数组不会翻译转义字符

我正在尝试使用 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

这个问题有两个方面:

  1. 您将 JSON 交给jqusing --arg,它需要文本。这意味着jq会将给定文本 JSON 编码为字符串。当传递的数据是 JSON 文档时,该jq实用程序有一个单独的选项。--argjson

  2. 在最一般的情况下,您不希望将 shell 变量注入到 JSON 文档中而不对其内容进行编码。您可以通过将变量的数据传递给jqusing--arg或使用一些其他jo需要非 JSON 输入并生成 JSON 输出的工具(例如 )来完成此操作。

  • 您还可以使用不加引号的方式,如果设置了 shell 选项(或等效的,如)[],这会导致 shell 抱怨。 shell默认设置了shell 选项。failglobnomatchzshzshnomatch

您的问题最好通过使用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"

相关内容