我正在尝试在现有的 JSON 文件中创建新的密钥对,其中键和值都作为变量发送。我有一个单行命令:
jq --arg key "$key" --arg value "$value" 'getpath(path('$key')) = '$value'' "$json"
其中: $key - key $value - value $json - 包含 JSON 数据的文件
例如,我的值是Linux CentOS
,所以当我运行命令时,我会得到
+ jq --arg key .operating_system.NAME --arg value 'CentOS Linux' 'getpath(path(.operating_system.NAME)) = CentOS' Linux ./servername_1648782569.json
jq: error: CentOS/0 is not defined at <top-level>, line 1:
getpath(path(.operating_system.NAME)) = CentOS
jq: 1 compile error
UPD:脚本面对它时我的 JSON 数据:
{
"operating_system": {}
}
我要粘贴的值
NAME="CentOS Linux"
来自
/etc/os-release
赋值函数:
function assign_value ()
{
if [ -z "$1" ]
then
echo __msg_error "Key is not passed as argument."
exit 1
elif [ -z "$2" ]
then
echo __msg_error "Value is not passed as argument."
exit 1
elif [ -z "$3" ]
then
echo __msg_error "JSON file path is not passed as argument."
exit 1
fi
key="$1"
value="$2"
json="$3"
tmp=$(mktemp)
jq --arg key "$key" --arg value "$value" "getpath(path("$key")) = "$value"" "$json" > "$tmp"
mv -- "$tmp" "$json"
}
args 传递给上面函数的地方
...
if test -e /etc/os-release
then
os_release_path='/etc/os-release'
else
os_release_path='/usr/lib/os-release'
fi
. "${os_release_path}"
MAJOR_VERSION_ID=$(echo $VERSION_ID | awk -F '.' '{print $1}')
initialize_new_area "$JSON_AREA" "$JSON"
#assign_value "${JSON_AREA}.NAME" "$NAME" "$JSON"
assign_value "${JSON_AREA}.ID" "$ID" "$JSON"
assign_value "${JSON_AREA}.ID_LIKE" "$ID_LIKE" "$JSON"
assign_value "${JSON_AREA}.MAJOR_VERSION_ID" "$MAJOR_VERSION_ID" "$JSON"
...
您正在使用 创建
jq
变量--arg
,但您从未在jq
表达式中使用这些变量。相反,您将 shell 变量注入到表达式中(因为您使用双引号)。这是您的问题的一部分。您也不能将数据
jq
作为字符串或有效 JSON 文档以外的任何内容传递,因此不可能给出表达式(类似 的路径)。.operating_system.NAME
相反,传递一个字符串并将其解析为路径语句。jq
在单引号表达式中使用变量jq
,并将给定的“键”值解析为可用作路径表达式的内容,方法jq
是将其拆分为点:请注意,上面的单引号将阻止 shell 扩展
$key
并$value
作为 shell 变量。相反,它们被视为jq
内部变量,具有您使用--arg
(正确编码jq
)分配给它们的值。测试:
为了支持以这种特定方式设置数组元素,您需要将路径元素转换为数字,但如果转换失败,则恢复为将它们用作字符串:
测试: