Wie aktualisiere ich einen einzelnen Wert in einem JSON-Dokument mit JQ?

103

Entschuldigung, wenn ich etwas sehr Offensichtliches übersehen habe; Ich habe gerade gefundenjq und versuche, damit einen JSON-Wert zu aktualisieren, ohne die umgebenden Daten zu beeinflussen.

Ich möchte ein curlErgebnis in jqeinen Wert weiterleiten, einen Wert aktualisieren und den aktualisierten JSON an einen weiterleiten curl -X PUT. Etwas wie

curl http://example.com/shipping.json | jq '.' field: value | curl -X PUT http://example.com/shipping.json

Bisher habe ich es zusammen mit gehackt sed, aber nachdem ich mir einige Beispiele des |=Operators angesehen jqhabe, bin ich mir sicher, dass ich diese nicht brauche.

Hier ist ein JSON-Beispiel - wie würde ich jqes festlegen "local": false, während der Rest des JSON erhalten bleibt?

{
  "shipping": {
    "local": true,
    "us": true,
    "us_rate": {
      "amount": "0.00",
      "currency": "USD",
      "symbol": "$"
    }
  }
}
STW
quelle

Antworten:

126

Sie legen Werte eines Objekts mit dem =Operator fest. |=Auf der anderen Seite wird ein Wert aktualisiert. Es ist ein subtiler, aber wichtiger Unterschied. Der Kontext der Filter ändert sich.

Verwenden Sie den =Operator, da Sie eine Eigenschaft auf einen konstanten Wert setzen .

.shipping.local = false

Beachten Sie nur, dass beim Festlegen eines Werts für eine Eigenschaft dieser nicht unbedingt vorhanden sein muss. Auf diese Weise können Sie einfach neue Werte hinzufügen.

.shipping.local = false | .shipping.canada = false | .shipping.mexico = true
Jeff Mercado
quelle
10
Dieses Beispiel ist nicht gut für den Normalwert. Wenn Sie also den Normalwert ändern müssen, müssen Sie ihn hinzufügen ", z .shipping.local = "new place". So wird der ganze Befehl sein curl http://example.com/shipping.json | jq '.shipping.local = "new place"'. Andernfalls erhalten Sie seltsame Fehler.
BMW
8
@BMW was? Hier ist es vollkommen in Ordnung. Jeder gültige JSON-Wert ist gültig, dies ist zufällig das Literal false. Werte müssen keine Zeichenfolgen sein.
Jeff Mercado
@BMW das OP will es einstellen mit false. Was ist los mit dir?
SOFe
17

Aktualisieren Sie einen Wert (setzt .foo.bar auf "neuer Wert"):

jq '.foo.bar = "new value"' file.json

Aktualisieren Sie einen Wert mithilfe einer Variablen (setzt .foo.bar auf "Hallo"):

variable="hello"; jq --arg variable "$variable" '.foo.bar = $variable' file.json
Paul Chris Jones
quelle
Ich habe dies als Beispiel verwendet, um ein NPM package.json über eine Shell umzubenennen, und es hat zu 100% funktioniert, danke.
Machado
2
Dies ersetzt nicht den Inhalt der Datei. Es wird nur auf Standard gedruckt. Sie müssen stout wieder in der Datei speichern, damit die Änderung bestehen bleibt. Siehe stackoverflow.com/a/60744617/1626687
spuder
1

Eine ähnliche Funktion wie der Operator | = ist map. map ist geeignet, um die Notwendigkeit eines vorherigen Filters für das Array zu vermeiden ...

Stellen Sie sich vor, Ihre Daten sind ein Array (in diesem Beispiel sehr häufig).

[
  {
    "shipping": {
      "local": true,
      "us": true,
      "us_rate": {
        "amount": "1.00",
        "currency": "USD",
        "symbol": "$"
      }
    }
  },
  {
    "shipping": {
      "local": true,
      "us": true,
      "us_rate": {
        "amount": "1.00",
        "currency": "USD",
        "symbol": "$"
      }
    }
  }
]

Daher ist es notwendig, das Array im Code wie folgt zu betrachten:

http://example.com/shipping.json | jq '.[] | .shipping.local = "new place"' | curl -X PUT http://example.com/shipping.json

oder um die Kartenfunktion zu verwenden, die so gestaltet ist, dass sie in jedem Array-Element als funktioniert

http://example.com/shipping.json | jq 'map(.shipping.local = "new place")' | curl -X PUT http://example.com/shipping.json

Überwachung

Für diejenigen, die lernen, haben Sie auch einige Fehler in der jq-Verwendung gemacht. Denken Sie nur daran, dass der 1. Parameter als Programm "gelesen" wird. Daher müssen alle gewünschten Befehle nach dem Aufruf von in die allererste Zeichenfolge aufgenommen werden Programm.

Thiago Conrado
quelle