2017-11-18 1 views
2

ich eine JSON mit dem folgenden Inhalt haben:Löschen von Objekten und Arrays mit jq, die einen Schlüssel (Anfänger) entsprechen

{ 
    "data": [ 
    { 
     "name": "Test", 
     "program": { 
     "publicAccess": "--------", 
     "externalAccess": false, 
     "userGroupAccesses": [ 
      { 
      "access": "r-------" 
      }, 
      { 
      "access": "rw------" 
      } 
     ], 
     "id": "MmBqeMLIC2r" 
     }, 
     "publicAccess": "rw------" 
    } 
    ] 
} 

Und ich möchte alle Schlüssel löschen (rekursiv), die publicAccess oder userGroupAccesses übereinstimmen, so dass meine JSON sieht wie folgt aus:

{ 
    "data": [ 
    { 
     "name": "Test", 
     "program": { 
     "externalAccess": false, 
     "id": "MmBqeMLIC2r" 
     } 
    } 
    ] 
} 

ich habe jq ‚s builtin walk Funktion von source kopiert.

# Apply f to composite entities recursively, and to atoms 
def walk(f): 
    . as $in 
    | if type == "object" then 
     reduce keys[] as $key 
     ({}; . + { ($key): ($in[$key] | walk(f)) }) | f 
    elif type == "array" then map(walk(f)) | f 
    else f 
    end; 

# My Code 
walk(if (type == "object" and .publicAccess) 
     then del(.publicAccess) 
    elif (type == "array" and .userGroupAccesses) 
     then del(.userGroupAccesses) 
    else 
     . 
end) 

Gibt mir jq: error (at <stdin>:2622): Cannot index array with string "userGroupAccesses". Auch wenn ich .userGroupAccesses[] verwende - Wie bekomme ich das Ergebnis?

Snippet auf jqplay: https://jqplay.org/s/1m7wAeHMTu

+0

Sie von einem alten builtin.jq kopiert. Es wäre sinnvoll, 'keys_unsorted' anstelle von' keys' zu verwenden. – peak

Antwort

4

Ihr Problem ist, wenn type == "array" wahr ist . ein Array sein wird, so wird .userGroupAccesses nicht funktionieren. Was Sie tun möchten, ist auf den Fall konzentrieren, wenn . ein Objekt ist. In Ihrem Anruf an walk müssen Sie nur nach type == "object" suchen und dann die Mitglieder entfernen, die Sie nicht möchten. z.B.

walk(if type == "object" then del(.publicAccess, .userGroupAccesses) else . end) 

Try it online at jqplay.org

Sie können dies auch ohne walk lösen, indem sie unter Verwendung Recursive Descent .. z.B.

del(.. | .publicAccess?, .userGroupAccesses?) 

Try it online at jqplay.org

Verwandte Themen