2017-08-23 5 views
0

ich Json-Datei, die in simmilar Weise aufgebaut ist:jq - neues Feld hinzufügen, mit ganzer Datei zu aktualisieren

[ 
{ 
"_id":"1234", 
"org":"org1", 
"int": 
    {"url":"http://url.com.uk:1234"}}, 
{ 
"_id":"4321", 
"org":"org2", 
"int": 
    {"url":"http://url.com.us:4321"}}, 
... 
] 

nun im „Springen“ von einem Eintrag zum anderen und überprüft, ob unter URL ordnungsgemäß funktioniert Anwendung. Nach der Überprüfung möchte ich das Feld "status" hinzufügen/aktualisieren. Aber ich kann nicht ganze Datei aktualisieren, im gerade bekommen:

$ jq --arg mod "GOOD" '.[0].int + {stat: $mod}' tmp.json 
{ 
    "url": "http://url.com.uk:1234", 
    "stat": "GOOD" 
} 

Wie kann ich mit jq Befehl erhalten neue, aktualisierte ganze Datei, nicht nur nur ein Teil davon?

Antwort

2

Wenn Sie Ihre Daten in data.json setzen und die Änderungen möchten Sie jeder Datensatz in einem separaten arg.json Argument machen Datei wie

{ 
    "1234": { "int": { "stat": "GOOD" } }, 
    "4321": { "int": { "stat": "BAD", "xxx": "yyy" } } 
} 

und laufen jq als

$ jq -M --argfile arg arg.json 'map(. + $arg[._id])' data.json 

dann gibt es die aktualisierten Daten aus, z.

[ 
    { 
    "_id": "1234", 
    "org": "org1", 
    "int": { 
     "stat": "GOOD" 
    } 
    }, 
    { 
    "_id": "4321", 
    "org": "org2", 
    "int": { 
     "stat": "BAD", 
     "xxx": "yyy" 
    } 
    } 
] 

Beachten Sie, dass die + Schlüssel ersetzt. Wenn Sie Schlüssel zusammenführen möchten, können Sie * z.

$ jq -M --argfile arg arg.json 'map(. * $arg[._id])' data.json 

die

[ 
    { 
    "_id": "1234", 
    "org": "org1", 
    "int": { 
     "url": "http://url.com.uk:1234", 
     "stat": "GOOD" 
    } 
    }, 
    { 
    "_id": "4321", 
    "org": "org2", 
    "int": { 
     "url": "http://url.com.us:4321", 
     "stat": "BAD", 
     "xxx": "yyy" 
    } 
    } 
] 

generiert Wenn Sie die Daten an seinem Platz aktualisieren möchten Sie sponge , wie in der Antwort Manipulate JSON with jq zum Beispiel verwenden könnte

+0

Dang, das wäre eine großartige Ergänzung zu [Dokumentation] (https://stackoverflow.com/documentation) gewesen. – ghoti

+0

Vielen Dank, es funktioniert für mich, aber es sieht eher wie Workaround als richtige Lösung aus. In bash sollte es einfacher sein als in Programmiersprachen (ich kann keine verwenden, es muss bash sein) und in diesem Fall ist es nicht. Mit json Bibliothek oder sogar in MongoDB JS ist es nur eine Zeile, um das benötigte Feld hinzuzufügen/zu aktualisieren. Dachte, es wird einen Schalter geben, mit dem ich erzwingen kann zu drücken, um alle Eingaben mit Updates wie "sed" auszugeben. Ich habe keine Ahnung, warum jq es schneidet. – user3069488

0

können Sie auf Array Karte und die int durch den Betrieb abfinden, wie:

jq --arg mod "GOOD" '.[] | .int=.int + {stat: $mod}' tmp.json 

{ 
    "_id": "1234", 
    "org": "org1", 
    "int": { 
    "url": "http://url.com.uk:1234", 
    "stat": "GOOD" 
    } 
} 
{ 
    "_id": "4321", 
    "org": "org2", 
    "int": { 
    "url": "http://url.com.us:4321", 
    "stat": "GOOD" 
    } 
} 
+0

Ich brauche die Ausgabe für die ganze Datei und aktualisiere jedes Segment getrennt mit dem richtigen Status (kein gleicher Zustand für jedes Segment wie in deinem Beispiel). – user3069488

+0

@ user3069488, ich denke, Sie können 'Select' dafür verwenden, wie zum Beispiel:' jq --arg mod "GOOD" '. [] | Wählen Sie (._ id == "1234") | .int = .int + {stat: $ mod} 'tmp.json ' – chengpohi

Verwandte Themen