2017-03-18 6 views
1

Unten ist die Vorlage meiner employee.json Dateidynamisch hinzufügen JSON-Objekt in einem Array mit jq

{ 
    "orgConfig": { 
     "departments": [] 
    } 
} 

wo Abteilungen Reihe von Abteilungen wie unter

{ 
    "name" : "physics", 
    "id" : "1234", 
    "head" : "abcd" 
} 

ähnlich

{ 
    "name" : "chemistry", 
    "id" : "3421", 
    "head" : "xyz" 
} 
haben

so die endgültige Array-Struktur, die ich erstellen möchte, ist wie folgt

{ 
    "orgConfig": { 
     "departments": [ 
      { 
       "name" : "physics", 
       "id" : "1234", 
       "head" : "abcd" 
      }, 
      { 
       "name" : "chemistry", 
       "id" : "3421", 
       "head" : "xyz" 
      }, 
      { 
       "name" : "Maths", 
       "id" : "4634", 
       "head" : "jklm" 
      } 
     ] 
    } 
} 

Unten ist der Code, wo ich die json Array-Elemente zu einem Abteilung dynamisch unter Fehler

#!/bin/bash 

source department.properties # will have departments=physiscs,chemistry,Maths,computers .. etc 
IFS=',' read -ra NAMES <<< "$departmentsToImport" 

position=0 
for i in "${NAMES[@]}"; do 
    #./jsonfiles will chemistry.json, physics.json, Maths.json etc 
    value=`cat ./jsonfiles/$i.json`  

    if [ $position -eq 0 ] 
    then 
     cat employee.json | jq --arg value "$value" '.orgConfig.departments[0] |= .+ $value' > tmp.json && mv tmp.json employee.json 
    else 
     cat employee.json | jq --arg position "$position" value "$value" '.orgConfig.departments[$position] |= .+ $value' > tmp.json && mv tmp.json employee.json 
    fi 
    ((position++)) 
    rm -rf tmp.json 
done 

exit $? 

aber Programm wirft

jq: error (at <stdin>:51): Cannot index array with string "1" 

Aber wenn Verwendung direkter Index anstelle der variablen Position am Hinzufügen dann funktioniert es gut.

cat employee.json | jq --argjson value "$value" '.orgConfig.departments[1] |= .+ $value' > tmp.json && mv tmp.json employee.json 

Ich weiß nicht, wie viele Schlüsselwertkarten von Abteilungen ich habe. Ich kann den Index nicht hart codieren. Irgendwelche Hilfe zu oben genanntem Problem und dynamisch JSON-Objekt in das Array hinzufügen?

Dank

Antwort

2

Die Aufgabe kann ohne Aufruf jq mehr als einmal durchgeführt werden.

Etwas sehr ähnlich wie die folgenden sollte ausreichen:

jq -s '{orgConfig: {departments: . }}' jsonfiles/*.json 

Diese Lösung setzt natürlich voraus, die .json Dateien alle gültig JSON halten.

Der Trick besteht darin, die Option -s zu verwenden, da diese die Eingabe in ein Array für Sie konvertiert. Sie werden wahrscheinlich feststellen, dass die Verwendung von -s zu besseren Laufzeiten führt als bei anderen Ansätzen.

+0

Dank @peak, bekam neue Anforderungen auf der Grundlage Lösung u oben gab. – user1876040

1

Dies kann durch Ausschalten der automatischen Eingangslesung jq erfolgen. Anschließend wird die erste explizite Eingabe über einen Filter geleitet, der seine Eingabe unter Verwendung der verbleibenden expliziten Eingaben ändert. Sinn ergeben? Nein :) Aber der Code selbst ist einfach:

jq -n 'input | .orgConfig.departments += [inputs]' \ 
    employee.json chemistry.json physics.json math.json 
  1. Die erste input liest aus dem ersten Argument (employee.json).
  2. Die += erhält ihren Eingang vom input Filter. Sein linker Operand wählt das zu aktualisierende Feld aus; Der rechte Operand liefert den Wert , um ihn zu aktualisieren.
  3. inputs liest aus den verbleibenden Befehlszeilenargumenten und legt ihren Inhalt in ein Array, jede Datei in einem separaten Element.

In Kombination mit dem Shell-Code den richtigen Kurs Dateien auszuwählen ergibt

source department.properties 
IFS=, read -ra NAMES <<< "$departmentsToImport" 
for c in "${NAMES[@]}"; do 
    courses+=("./jsonfiles/$c.json") 
done 
jq -n 'input | .orgConfig.departments += [inputs]' employee.json "${courses[@]}" 
+0

Danke @chepner für die große Hilfe. Mein Problem wurde gelöst. – user1876040

Verwandte Themen