522 Stimmen

Verwendung von jq zum Analysieren und Anzeigen mehrerer Felder in einem JSON seriell

Ich habe dieses Json

{
    "users": [
        {
            "first": "Stevie",
            "last": "Wonder"
        },
        {
            "first": "Michael",
            "last": "Jackson"
        }
    ]
}

Mit jq möchte ich den Vornamen und Nachnamen nacheinander anzeigen. So -

Stevie Wonder
Michael Jackson

Das ist mein bisheriger Fortschritt -

jq '.users[].first, .users[].last'

Aber es zeigt

"Stevie"
"Michael"
"Wonder"
"Jackson"

Beachten Sie folgendes:

  1. Die doppelten Anführungszeichen, die ich nicht möchte.
  2. Der Zeilenumbruch, den ich nicht möchte.
  3. Es ist durcheinander. Meine Abfrage zeigt zuerst alle Vornamen und dann alle Nachnamen an. Ich möchte jedoch Vornamen-Nachnamen, Vornamen-Nachnamen-Pärchen.

18voto

TinyRoy Punkte 309

Dies wird ein Array von Namen produzieren

> jq '[ .users[] | (.first + " " + .last) ]' ~/test.json

[
  "Stevie Wonder",
  "Michael Jackson"
]

17voto

machzqcq Punkte 1009

Während beide der obigen Antworten gut funktionieren, wenn key,value Strings sind, hatte ich eine Situation, in der ich einen String und eine Ganzzahl anhängen musste (jq Fehler bei Verwendung der obigen Ausdrücke)

Anforderung: Um eine URL aus dem unten stehenden JSON zu konstruieren

pradeep@seleniumframework>curl http://192.168.99.103:8500/v1/catalog/service/apache-443 | jq .[0]
  % Gesamt    % Empfangen % Übertragen  Durchschnittliche Geschwindigkeit   Zeit    Zeit     Zeit  Aktuell
                                 Dload  Upload   Gesamt   Verstrichen Zeit    Aktuell
100   251  100   251    0     0   155k      0 --:--:-- --:--:-- --:--:--  245k
{
  "Node": "myconsul",
  "Address": "192.168.99.103",
  "ServiceID": "4ce41e90ede4:compassionate_wozniak:443",
  "ServiceName": "apache-443",
  "ServiceTags": [],
  "ServiceAddress": "",
  "ServicePort": 1443,
  "ServiceEnableTagOverride": false,
  "CreateIndex": 45,
  "ModifyIndex": 45
}

Lösung:

curl http://192.168.99.103:8500/v1/catalog/service/apache-443 |
jq '.[0] | "http://" + .Address + ":" + "\(.ServicePort)"'

6voto

ThorSummoner Punkte 13974

Ich habe ziemlich nah dran gekommen, was ich wollte, indem ich so etwas gemacht habe

cat my.json | jq '.my.prefix[] | .primary_key + ":", (.sub.prefix[] | "    - " + .sub_key)' | tr -d '"' 

Der Output davon ist nah genug an yaml, sodass ich es normalerweise ohne viel Probleme in andere Tools importieren kann. (Ich suche immer noch nach einer Möglichkeit, eine Untermenge des Eingabe-Json grundlegend zu exportieren)

0voto

WesternGun Punkte 9127

Ein paar mehr Schritte, aber mir ist aufgefallen, dass hier niemand join() erwähnt. join() funktioniert nur für Arrays, also musst du eins konstruieren. Um doppelte Anführungszeichen zu eliminieren, verwende -r:

echo $JSON | jq -r '.users[] | [.first,.last] | join(" ")'

, bedeutet, dass der Filter auf die Ausgabe des vorherigen Schritts angewendet wird und zwar in dieser Reihenfolge, also zuerst .first dann erhältst du .last und erstellst ein Array.

Ein kleiner Test zeigt keine Leistungseinbußen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X