jq - adiciona objetos do arquivo no array json

2

Eu quero adicionar uma matriz com elementos e valor em um arquivo json existente usando jq.

Eu já tenho um arquivo (input.json) com

{
  "id": 9,
  "version": 0,
  "lastUpdTs": 1532371267968,
  "name": "Training"
}

Eu quero adicionar isso em outra matriz de grupos para este 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 ser parecido com

[
  {
    "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 adicionar elementos em uma matriz, mas não sei como passar de um arquivo.

jq '.[].groups += [{"INPUT": "HERE"}]' ./orig.json
    
por CLO 07.08.2018 / 09:38

2 respostas

2

jq tem um sinalizador para alimentar o conteúdo real do JSON com seu sinal --argjson . O que você precisa fazer é armazenar o conteúdo do primeiro arquivo JSON em uma variável no contexto de jq e atualizá-lo no segundo JSON

jq --argjson groupInfo "$(<input.json)" '.[].groups += [$groupInfo]' orig.json

A parte "$(<input.json)" é a construção de redirecionamento de shell para gerar o conteúdo do arquivo fornecido e com o argumento para --argjson é armazenado na variável groupInfo . Agora você adiciona-o à matriz groups na parte real do filtro.

Colocando de outra forma, a solução acima é equivalente a fazer isso

jq --argjson groupInfo '{"id": 9,"version": 0,"lastUpdTs": 1532371267968,"name": "Training" }' \
   '.[].groups += [$groupInfo]' orig.json
    
por 07.08.2018 / 09:43
3

Este é o caso exato em que a função input é para:

input and inputs [...] read from the same sources (e.g., stdin, files named on the command-line) as jq itself. These two builtins, and jq’s own reading actions, can be interleaved with each other.

Ou seja, jq lê um objeto / valor do arquivo e executa o pipeline nele, e em qualquer lugar input aparece a entrada seguinte é lida e usada como resultado da função.

Isso significa que você pode fazer:

jq '.[].groups += [input]' orig.json input.json

com exatamente o comando que você já escreveu, além de input como o valor. A expressão input será avaliada para o (primeiro) objeto lido a partir do próximo arquivo na lista de argumentos, neste caso, todo o conteúdo de input.json .

Se você tiver vários itens para inserir, você pode usar inputs com o mesmo significado. Ele será aplicado a um único ou vários arquivos da linha de comando igualmente e [inputs] representa todos os corpos de arquivos como uma matriz.

Também é possível intercalar coisas para processar vários arquivos orig , cada um com um arquivo complementar inserido, mas separar as saídas seria um incômodo.

    
por 07.08.2018 / 09:54

Tags