2017-12-22 4 views
2

Ich habe eine große Menge von Daten, ich benutze JQ, um das Objekt zu konstruieren, das nur die Daten enthält, an denen ich mich für einen Datensatz interessiere. Mein Problem ist, dass ich doppelte Objekte sehe, es scheint, dass meine Syntax falsch ist.JQ-Filterung auf Feldern in verschachtelten Objekten

Ich arbeite mit einem Objekt, das flache Felder und ein Array von Unterobjekten enthält, es gibt bestimmte Felder, die ich herausziehen möchte, und mache neue Objekte, die alle gewünschten Daten haben. Einschließlich einiger flacher Felder und einiger Felder von den Array-Objekten.

Hier ist ein kleiner Beispiel, das Problem tmpData.json

{ 
"id": "0001", 
"type": "donut", 
"name": "Cake", 
"ppu": 0.55, 
"batter": [{ 
     "id": "1001", 
     "type": "Regular" 
    }, 
    { 
     "id": "1002", 
     "type": "Chocolate" 
    }, 
    { 
     "id": "1003", 
     "type": "Blueberry" 
    }, 
    { 
     "id": "1004", 
     "type": "Devil's Food" 
    } 
] 
} 

dieses Ich betreibe demonstrieren hilft: cat tmpData.txt | jq {'id: .id, type: .type, batter: .batter[].id'}

Welche gibt diese nicht-json Menge von Objekten

{ 
    "id": "0001", 
    "type": "donut", 
    "batter": "1001" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batter": "1002" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batter": "1003" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batter": "1004" 
} 
(es Komma fehlt)

Das ist gut. Ich habe jetzt Objekte, die jeweils die Eltern-ID 0001 enthalten, und die verschiedenen Elemente im Array sind jedem Objekt zugeordnet.

Wenn ich laufen: cat tmpData.txt | jq {'id: .id, type: .type, batterID: .batter[].id, batterType: .batter[].type'}

Mit dem zusätzlichen type Feld ich viele Duplikate erhalten, die fälschlicherweise Elemente verknüpfen

{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1001", 
    "batterType": "Regular" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1001", 
    "batterType": "Chocolate" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1001", 
    "batterType": "Blueberry" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1001", 
    "batterType": "Devil's Food" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1002", 
    "batterType": "Regular" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1002", 
    "batterType": "Chocolate" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1002", 
    "batterType": "Blueberry" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1002", 
    "batterType": "Devil's Food" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1003", 
    "batterType": "Regular" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1003", 
    "batterType": "Chocolate" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1003", 
    "batterType": "Blueberry" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1003", 
    "batterType": "Devil's Food" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1004", 
    "batterType": "Regular" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1004", 
    "batterType": "Chocolate" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1004", 
    "batterType": "Blueberry" 
} 
{ 
    "id": "0001", 
    "type": "donut", 
    "batterID": "1004", 
    "batterType": "Devil's Food" 
} 

Jetzt sehe ich, dass jeder batterID mit jeder Art in einem Objekt ist regular, chocolate, blueberry. Aber in der Tat 1002 ist nur chocolate.

Mein idealer Ausgang wäre wie diese

[{ 
"id": "0001", 
"type": "donut", 
"batterID": "1001", 
"batterType": "Regular" 
}, 
{ 
"id": "0001", 
"type": "donut", 
"batterID": "1002", 
"batterType": "Chocolate" 
}] 

Ihr Know-how zu schätzen wissen!

EDIT GELÖST: Arbeitsbefehl: cat tmpData.txt | jq '[{id, type} + (.batter[] | {batterId: .id, batterType: .type})]'

Antwort

4
  1. Der Ausgang "ohne Komma" ist ein Strom von JSON; Um ein Array auszugeben, wickeln Sie Ihren jq-Filter in eckige Klammern.
  2. Sie können {id: id, type: .type} zu {id, type}
  3. Ihre Filter abkürzen, die .batter wiederholt [] hat den Effekt, ein kartesisches Produkt zu schaffen. Was Sie offensichtlich wollen stattdessen ist, um .batter nur einmal zu erweitern.

Putting alles zusammen:

[{id, type} + (.batter[] | {batterId: .id, batterType: .type})] 
+0

Ich erhalte den Fehler '' '-bash: Syntaxfehler in der Nähe von unerwartetem Token' (‘' '' Können Sie zeigen, wie dies mit dem JQ Befehl aussieht? @peak – Goldfish

+0

Versuchen Sie, das jq-Programm in eine Datei zu setzen, sagen Sie program.jq, und rufen Sie jq mit der Option -f auf, zB 'jq -f program.jq tmpData.json' – peak

+0

Es stellte sich heraus, dass ich nur die Datei einschließen musste ganze JQ Befehl in einfachen Anführungszeichen .. Siehe bearbeiten .. Danke !! – Goldfish

Verwandte Themen