2017-10-05 5 views
0

-je recevoir le fichier d'entrée suivant:JQ: conditionnellement mise à jour/REMPLACER/ajouter des éléments JSON en utilisant un fichier d'entrée

  • input.json:
[ 
{"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
{"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":18,"FLAG":"0"}, 
{"ID":"aaa_12301248","time_CET":"00:30:00","VALUE":160,"FLAG":"0"}, 

{"ID":"bbb_0021122","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"bbb_0021122","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"bbb_0021122","time_CET":"00:30:00","VALUE":22,"FLAG":"0"}, 

{"ID":"ccc_0021122","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ccc_0021122","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ccc_0021122","time_CET":"00:30:00","VALUE":20,"FLAG":"0"}, 

{"ID":"ddd_122455","time_CET":"00:00:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ddd_122455","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
{"ID":"ddd_122455","time_CET":"00:30:00","VALUE":null,"FLAG":"?"}, 
] 

Comme vous pouvez voir qu'il y a des valeurs valides (FLAG: 0) et des valeurs invalides (FLAG: "?"). Maintenant, je obtenu un fichier qui ressemble à ceci (un pour chaque ID):

aaa.json:

[ 
    {"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":null,"FLAG":"?"}, 
    {"ID":"aaa_12301248","time_CET":"00:55:00","VALUE":45,"FLAG":"0"} 
] 

Comme vous pouvez le voir, objet on est le même que dans input.json mais l'objet deux est invalide (FLAG: "?"). C'est pourquoi l'objet 2 doit être remplacé par l'objet correct de input.json (avec VALUE: 18). Les objets peuvent être identifiés par les éléments "time_CET" et "ID".

De plus, il y aura de nouveaux objets dans input.json, qui n'ont pas fait partie de aaa.json etc. Ces objets doivent être ajoutés au tableau, et les objets valides de aaa.json doivent être conservés.

En fin de compte, aaa.json devrait ressembler à ceci:

[ 
    {"ID":"aaa_12301248","time_CET":"00:00:00","VALUE":10,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:15:00","VALUE":18,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:30:00","VALUE":160,"FLAG":"0"}, 
    {"ID":"aaa_12301248","time_CET":"00:55:00","VALUE":45,"FLAG":"0"} 
] 

Donc, pour résumer:

  1. look pour FLAG: "?" dans aaa.json
  2. remplacez cet objet par l'objet correspondant de input.json en utilisant "ID" et "time_CET" pour le mappage.
  3. Gardez exisiting objets valides et ajouter des objets à partir input.json que n'existait pas en aaa.json avant (cela signifie que des objets à partir avec « aaa » dans le champ « ID »)
  4. Répétez cette opération pour bbb.json , ccc.json et ddd.json

Je ne suis pas sûr qu'il soit possible de faire cela en une seule fois avec une commande comme celle-ci, parce que la sortie doit retourner aux bons fichiers d'identification (aaa, bbb ccc.json):

jq --argfile aaa aaa.json --argfile bbb bbb.json .... -f prog.jq input.json 

Le Le problème est que le numéro après l'identifiant (aaa, bbb, ccc etc.) peut changer. Donc, pour assurer que les objets sont ajoutés au fichier/tableau correct, une déclaration comme celui-ci serait nécessaire:
if (."ID"|contains("aaa")) then ....

Ou est-il préférable d'exécuter le programme plusieurs fois avec différents paramètres d'entrée? Je ne suis pas sûr ..

Merci d'avance!

Répondre

0

Voici une approche

#!/bin/bash 

# usage: update.sh input.json aaa.json bbb.json.... 
# updates each of aaa.json bbb.json.... 

input_json="$1" 
shift 

for i in "[email protected]"; do 
    jq -M --argfile input_json "$input_json" ' 

     # functions to restrict input.json to keys of current xxx.json file 
     def prefix:    input_filename | split(".")[0]; 
     def selectprefix:  select(.ID | startswith(prefix)); 

     # functions to build and probe a lookup table 
     def pk:     [.ID, .time_CET]; 
     def lookup($t;$k):  $t | getpath($k); 
     def lookup($t):   lookup($t;pk); 
     def organize(s):   reduce s as $r ({}; setpath($r|pk; $r)); 

     # functions to identify objects in input.json missing from xxx.json 
     def pks:     paths | select(length==2); 
     def missing($t1;$t2): [$t1|pks] - [$t2|pks] | .[]; 
     def getmissing($t1;$t2): [ missing($t1;$t2) as $p | lookup($t1;$p)]; 

     # main routine 
     organize(.[]) as $xxx 
     | organize($input_json[] | selectprefix) as $inp 
     | map(if .FLAG != "?" then . else . += lookup($inp) end) 
     | . + getmissing($inp;$xxx) 

    ' "$i" | sponge "$i" 

done 

Le script utilise JQ dans une boucle pour lire et mettre à jour chaque aaa.json ... fichier.

Le filtre crée des objets temporaires pour faciliter la recherche de valeurs par [ID,time_CET], met à jour toutes les valeurs du aaa.json avec un FLAG == "?" et ajoute finalement toutes les valeurs de input.json qui manquent dans aaa.json.

La table de recherche temporaire pour input.json utilise input_filename afin que seules les clés commençant par un préfixe correspondant au nom du fichier actuellement traité soient incluses.

Sample Run:

$ ./update.sh input.json aaa.json 

aaa.json après course:

[ 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:00:00", 
    "VALUE": 10, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:15:00", 
    "VALUE": 18, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:55:00", 
    "VALUE": 45, 
    "FLAG": "0" 
    }, 
    { 
    "ID": "aaa_12301248", 
    "time_CET": "00:30:00", 
    "VALUE": 160, 
    "FLAG": "0" 
    } 
] 
+0

Salut! Merci pour votre réponse. Cela fonctionne très bien avec l'échantillon. Cependant, s'il y a plus d'un objet à ajouter, cela crée un nouveau tableau et ne l'ajoute pas au tableau initial de aaa.json. Ajoutez simplement cette ligne à input.json et vous verrez: '{"ID": "aaa_0021122", "time_CET": "00:45:00", "VALUE": 22, "FLAG": "?"}, 'Je veux seulement un tableau dans les fichiers aaa/bbb/ccc.json, pas un tableau par objet ajouté. Merci pour l'instant! – user2556342

+0

Je vois. J'avais un '' '' '' '' '' '' '' au mauvais endroit dans la définition de 'getmissing'. Cette version devrait fonctionner. En tant qu'exercice d'apprentissage, vous voudrez peut-être voir si vous pouvez comprendre pourquoi placer le début du constructeur de tableau à cet endroit particulier a l'effet qu'il a. – jq170727