2016-04-15 9 views
1

Ich versuche, jq zu kombinieren zwei Arrays und läuft in ein bisschen Ärger.Parse Netdata JSON-Ausgabe (Mulltiple-Arrays) mit jq

Ich versuche, die Daten von netdata (netdata.firehol.org) zu analysieren und die beiden Daten in der JSON-Antwort, die mich interessieren, sind beide Teil eines Arrays. Das erste Array ist Etiketten für die Datenpunkte in der zweiten Reihe.

Beispieleingabe

[ 
    "time", 
    "guest_nice", 
    "guest", 
    "steal", 
    "softirq", 
    "irq", 
    "user", 
    "system", 
    "nice", 
    "iowait" 
] 
[ 
    1460728600, 
    0, 
    0, 
    0, 
    0.45731, 
    0, 
    0.25108, 
    11.74702, 
    48.22465, 
    0 
] 

Eingang

Wenn Sie sich frische Daten greifen wollen t est gegen, können Sie die folgenden Schritte aus:

curl -s -X GET --header 'Accept: application/json' 
'http://netdata.firehol.org/api/v1/data?chart=system.cpu&after=-10&before=0&points=1&group=average&format=json&options=seconds%2Cjsonwrap' | jq '.result.labels, .result.data[]' 

Ich habe versucht Karte() zu verwenden, sowie versuchen, Vars zu beiden Arrays zuweisen und dann aus den Objekten drucken zusammen, aber erfolglos geblieben sind (siehe unten) .

-Code

| jq '.result.labels as $labels | .result.data[] as $data | .result.data[] | Label: $labels[.], data: $data[.]}' 

ich jemand Einsicht im Voraus zu schätzen weiß, wie ich etwas bin stecken, und würde es vorziehen, um dies eher in jq alles tun, als for-Schleifen in der Bash (falls möglich).

Erwartet Ouput

{ "Zeit": "1460728600", "guest_nice": "0", ... }

Antwort

1

Sie haben nicht genau angegeben, wie Sie wollen die zu kombinierenden Arrays, aber ein Ansatz besteht darin, transpose zu verwenden, was in diesem Fall effektiv eine Art von zip ist.Zum Beispiel:

$ jq -n -c '[["a","b"], [1,2]] | transpose' 

ergibt: [["a",1],["b",2]]

Wenn Sie ein Array von Objekten, dann mit dem gleichen Eingang,

transpose | map({ (.[0]) : .[1] }) 

ergäbe wollte: [{"a":1},{"b":2}]

Wenn Ihr jq tut nicht haben transpose, hier ist seine Definition:

# transpose a possibly jagged matrix, quickly; 
# rows are padded with nulls so the result is always rectangular. 
def transpose: 
    [range(0; (map(length) | max)) as $j 
    | [range(0; length) as $i | .[$i][$j] ] ] ; 

Alternativ, wenn Sie lieber eine sehr kurze zip:

def zip: [range(0; .[0]|length) as $i | [.[0][$i], .[1][$i]]]; 
0

Hier ist eine Lösung, die den allgemeinen Fall behandelt, wo das erste Array mit den Schlüsselnamen enthält und die folgenden Felder Werte enthalten, wobei man transponieren und from_entries

{h:.[0], v:.[1:][]}      # {h:[keys], v:[values]} 
| [.h, .v]         # [ [keys], [values] ] ... 
| [ transpose[] | {key:.[0], value:.[1]} ] # [ {"key":key, "value":value}, ... ] 
| from_entries        # { key:value, key:value, ... } 

Zum Beispiel, wenn diese Filter in filter.jq und data.json enthält

["time","guest_nice","guest","steal","softirq","irq","user","system","nice","iowait"] 
[1460728600,0,0,0,0.45731,0,0.25108,11.74702,48.22465,0] 
[1460728601,0,0,0,0.45732,0,0.25109,12.74703,49,0] 

dann der Befehl

jq -M -s -c -f filter.jq data.json 

produziert

{"time":1460728600,"guest_nice":0,"guest":0,"steal":0,"softirq":0.45731,"irq":0,"user":0.25108,"system":11.74702,"nice":48.22465,"iowait":0} 
{"time":1460728601,"guest_nice":0,"guest":0,"steal":0,"softirq":0.45732,"irq":0,"user":0.25109,"system":12.74703,"nice":49,"iowait":0}