Eu quero adicionar uma matriz com elementos e valor em um arquivo json existente usando jq.
Já tenho um arquivo (input.json) com
{
"id": 9,
"version": 0,
"lastUpdTs": 1532371267968,
"name": "Training"
}
Eu quero adicionar isso em outra matriz de grupos neste json (orig.json)
[
{
"name": "JAYS",
"sourceConnection": {
"name": "ORACLE_connection",
"connectionType": "JDBC",
"commProtocol": "JDBC"
},
"checked": true,
"newlyAdded": false,
"id": null,
"groups": [],
"displayName": "SCOTT",
"defaultLevel": "MANAGED"
}
]
O resultado final deve parecer
[
{
"name": "JAYS",
"sourceConnection": {
"name": "ORACLE_connection",
"connectionType": "JDBC",
"commProtocol": "JDBC"
},
"checked": true,
"newlyAdded": false,
"id": null,
"groups": [
{
"id": 9,
"version": 0,
"lastUpdTs": 1532371267968,
"name": "Training"
}
],
"displayName": "SCOTT",
"defaultLevel": "MANAGED"
}
]
Eu sei como adicionar elementos em uma matriz, mas não sei como passar de um arquivo.
jq '.[].groups += [{"INPUT": "HERE"}]' ./orig.json
jq
tem um sinalizador para alimentar o conteúdo JSON real com seu--argjson
sinalizador. O que você precisa fazer é armazenar o conteúdo do primeiro arquivo JSON em uma variável nojq
contexto de e atualizá-lo no segundo JSONA parte
"$(<input.json)"
é a construção de redirecionamento do shell para gerar o conteúdo do arquivo fornecido e com o argumento para--argjson
ele é armazenado na variávelgroupInfo
. Agora você o adiciona àgroups
matriz na parte do filtro real.Colocando de outra forma, a solução acima é equivalente a fazer isso
Este é o caso exato em que a
input
função é para:Ou seja,
jq
lê um objeto/valor do arquivo e executa o pipeline nele, e em qualquer lugarinput
aparece a próxima entrada é lida e usada como resultado da função.Isso significa que você pode fazer:
com exatamente o comando que você já escreveu, mais
input
como o valor. Ainput
expressão será avaliada para o (primeiro) objeto lido do próximo arquivo na lista de argumentos, neste caso todo o conteúdo deinput.json
.Se você tiver vários itens para inserir, poderá usar
inputs
com o mesmo significado. Ele será aplicado em um único ou vários arquivos da linha de comando igualmente e[inputs]
representará todos os corpos de arquivo como uma matriz.Também é possível intercalar coisas para processar vários
orig
arquivos, cada um com um arquivo complementar inserido, mas separar as saídas seria um incômodo.Novas versões de
jq
suporteslurpfile
Isso alcança o resultado que você está procurando:
jq '.[].groups += $inputs' orig.json --slurpfile inputs input.json
Testado em jq 1.6
Usar ponto como espaço reservado
Resultado: