Filtern von JSON-Anfragen mit JQ und Bash-Skripting

Filtern von JSON-Anfragen mit JQ und Bash-Skripting

Ich fordere von Twitch ein JSON an mit: curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1Wo $1ist die Eingabe, die ich für meine Funktion sende.

Jetzt möchte ich das JSON filtern, indem ich das hier nach dem Curl einfüge: | jq '.stream.channel.something' Ich versuche, durch JQ-Filterung drei verschiedene Zeichenfolgenwerte abzurufen. Ich schaffe es, sie auf dieses Niveau zu bringen:

{
    "first": "lor"
    "second": "em"
    "third": "ipsum"
}

Wie kann man mit ihnen innerhalb des Codes arbeiten?


Die Alternativen, die mir eingefallen sind, sind:

  1. Erstellen Sie eine Curl-Ausgabe, filtern Sie diese und löschen Sie sie anschließend.
  2. Senden Sie 3 cURL-Anfragen – (Nutzloser Leistungsfresser?).

Antwort1

Wie gesagt, ich kenne mich nicht gut mit JSON oder JQ aus, aber ich konnte JQ nicht dazu bringen, Ihre Beispielausgabe zu analysieren:

{
    "first": "lor"
    "second": "em"
    "third": "ipsum"
}

parse error: Expected separator between values at line 3, column 12

Also habe ich die Eingabe wie folgt umgewandelt:

{
  "stream" : {
    "channel" : {
      "something" : {
        "first": "lor",
        "second": "em",
        "third": "ipsum"
      }
    }
  }
}

... basierend auf dem, was ich aus Ihrem Aufruf von jq entnommen habe. Hoffentlich ist das ähnlich zu dem, was der Curl-Befehl ausgibt.

Wenn ja, dann scheint diese Sequenz das gewünschte Ergebnis zu liefern:

# this is just your original curl command, wrapped in command substitution,
# in order to assign it to a variable named 'output':
output=$(curl --silent -H 'Accept: application/vnd.twitchtv.v3+json' -X GET https://api.twitch.tv/kraken/streams/$1)

# these three lines take the output stream from above and pipe it to
# separate jq calls to extract the values; I added some pretty-printing whitespace
first=$( echo "$output" | jq '.["stream"]["channel"]["something"]["first"]' )
second=$(echo "$output" | jq '.["stream"]["channel"]["something"]["second"]')
third=$( echo "$output" | jq '.["stream"]["channel"]["something"]["third"]' )

Mit den Ergebnissen:

$ echo $first
"lor"
$ echo $second
"em"
$ echo $third
"ipsum"

Antwort2

Angenommen, Ihre Datei ist gültiges JSON (was bei den Daten in der Frage nicht der Fall ist):

{
  "first": "lor",
  "second": "em",
  "third": "ipsum"
}

jqDamit lassen sich drei Zuweisungen erstellen, die man dann sicher in der Shell auswerten kann:

eval "$(
    jq -r '
        @sh "first=\(.first)",
        @sh "second=\(.second)",
        @sh "third=\(.third)"' file.json
)"

Der @shOperator „in“ jqgibt Zuweisungen im Formular aus, first='lor'damit sie von der Shell ausgewertet werden können.

Für die bashShell könnte man auch eine Array-Zuweisung erstellen:

eval "$(
    jq -r '@sh "array=(\([.first, .second, .third]))"' file.json
)"

Hier jqwürde der Befehl etwas wie generieren array=('lor' 'em' 'ipsum'), das bei der Auswertung bashdas aufgerufene Array arraymit dem angegebenen Inhalt erstellen würde.

Sie können die jqAnweisung verwenden @sh "array=(\([.[]]))", um ein Array mit den Werten aller Schlüssel zu erstellen, wobei Sie davon ausgehen, dass jeder Wert ein Skalar ist.

verwandte Informationen