Estou tentando criar um novo par de chaves no arquivo JSON existente, onde a chave e o valor são enviados como variáveis. Eu tenho o comando de uma linha:
jq --arg key "$key" --arg value "$value" 'getpath(path('$key')) = '$value'' "$json"
onde: $key - key $value - value $json - arquivo contendo dados JSON
Por exemplo, meu valor é Linux CentOS
, então quando estou executando o comando, obterei
+ 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 : Meus dados JSON no momento em que o script o enfrenta:
{
"operating_system": {}
}
O valor que estou tentando colar é
NAME="CentOS Linux"
de
/etc/os-release
a função que atribui valores:
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"
}
o lugar de onde os argumentos passaram a funcionar acima
...
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"
...
Você está criando
jq
variáveis com--arg
, mas nunca as usa em suajq
expressão. Em vez disso, você injeta as variáveis do shell na expressão (já que usa aspas duplas). Isso faz parte do seu problema.Você também não pode passar dados
jq
como nada além de uma string ou um documento JSON válido, portanto, é impossível fornecer uma expressão (um caminho como )..operating_system.NAME
Em vez disso, passe uma string e analise-a em uma instrução de caminho.Use as
jq
variáveis em umajq
expressão entre aspas simples e analise o valor "chave" fornecido em algo que possa ser usado como uma expressão de caminhojq
, dividindo-o em pontos:Observe que as aspas simples acima impedirão que o shell se expanda
$key
e$value
como variáveis do shell. Em vez disso, elas são tratadas comojq
variáveis internas com os valores que você atribuiu a elas usando--arg
(codificada adequadamente porjq
).Teste:
Para dar suporte à configuração de elementos de matriz dessa maneira específica, você precisa converter os elementos de caminho em números, mas voltar a usá-los como strings se essa conversão falhar:
Teste: