2017-09-19 5 views
0

J'ai un fichier JSON que j'utilise pour le travail que je dois analyser ce qui est dans le format suivant:Impossible d'obtenir JQ de reconnaître un tableau dans un fichier JSON

(^)#(^)#(^)#(^)[email protected]:~$ cat jqtest 
{ 
    "files":[ 
     { 
     "BLOCK1":{ 
      "SUBBLOCK1":{ 
       "akey1":"avalue1", 
       "bkey1":"bvalue1", 
       "ckey1":"cvalue1" 
      }, 
      "dkey1":"dvalue1", 
      "key":"evalue1" 
     } 
     }, 
     { 
     "BLOCK-2":{ 
      "SUBBLOCK2":{ 
       "akey2":"avalue2", 
       "bkey2":"bvalue2" 
      }, 
      "ckey2":"cvalue2", 
      "key":"dvalue2" 
     } 
     }, 
     { 
     "BLOCK-A":{ 
      "SUBBLOCK2":{ 
       "akey2":"avalue2", 
       "bkey2":"bvalue2" 
      }, 
      "ckey2":"cvalue2", 
      "key":"dvalue2" 
     } 
     }], 
    "NOBLOCK":"value", 
    "key":"NOBLOCKvalue" 
} 

Il est donc un tableau imbriqué dans un fichier json. jq .[] jqtest me donne tout dans le fichier. Même les données en dehors du tableau. Sauf, en dehors du tableau, je ne compte tenu des valeurs pas les clés:

(^)#(^)#(^)#(^)[email protected]:~$ jq .[] jqtest 
[ 
    { 
    "BLOCK1": { 
     "SUBBLOCK1": { 
     "akey1": "avalue1", 
     "bkey1": "bvalue1", 
     "ckey1": "cvalue1" 
     }, 
     "dkey1": "dvalue1", 
     "key": "evalue1" 
    } 
    }, 
    { 
    "BLOCK-2": { 
     "SUBBLOCK2": { 
     "akey2": "avalue2", 
     "bkey2": "bvalue2" 
     }, 
     "ckey2": "cvalue2", 
     "key": "dvalue2" 
    } 
    }, 
    { 
    "BLOCK-A": { 
     "SUBBLOCK2": { 
     "akey2": "avalue2", 
     "bkey2": "bvalue2" 
     }, 
     "ckey2": "cvalue2", 
     "key": "dvalue2" 
    } 
    } 
] 
"value" 
"NOBLOCKvalue" 
(^)#(^)#(^)#(^)[email protected]:~$ 

Au-delà, je ne peux pas accéder à un bloc à l'intérieur du tableau:

(^)#(^)#(^)#(^)[email protected]:~$ jq '.[].BLOCK1' jqtest 
jq: error (at jqtest:36): Cannot index array with string "BLOCK1" 
(^)#(^)#(^)#(^)[email protected]:~$ jq '.[].BLOCK-2' jqtest 
jq: error (at jqtest:36): Cannot index array with string "BLOCK" 
(^)#(^)#(^)#(^)[email protected]:~$ jq '.[].BLOCK-A' jqtest 
jq: error: A/0 is not defined at <top-level>, line 1: 
.[].BLOCK-A   
jq: 1 compile error 
(^)#(^)#(^)#(^)[email protected]:~$ 

Comment puis-je accéder au tableau ?

+2

Le tableau est assis dans la propriété 'files' ... accéder au' files' propriété ... '.files' –

+0

' jq '.files | [] | .BLOCK1 'jqtest' fonctionne. 'jq '.files | [] | .BLOCK-2 'jqtest' donne cette erreur: 'jq: erreur (at jqtest: 36): null (null) et le nombre (2) ne peut pas être soustrait'. 'jq '.files | [] | .BLOCK-A 'jqtest' donne cette erreur: 'jq: erreur: A/0 n'est pas défini à , ligne 1:/.files | [] | .BLOCK-A/jq: 1 erreur de compilation ». –

+1

Lors de l'utilisation de la syntaxe '.name', les noms doivent suivre les règles de dénomination d'identifiant habituelles trouvées dans la plupart des langages de programmation. '-' n'est pas un caractère d'identification valide, vous devez utiliser la syntaxe d'index d'objet:'. "BLOCK-A" 'ou'. ["BLOCK-A"] '. –

Répondre

0

Le tableau d'objets avec des clés non uniformes rend les choses un peu compliquées ici. Une fois que vous avez dépassé .files, vous devez commencer à utiliser Array Iteration [] pour accéder à ces éléments, puis utiliser les opérations d'objet comme keys pour aller plus loin.

Voici une fonction qui peut aider dans cette situation. Il scanne .files pour un objet avec une clé correspondant à la clé spécifiée et renvoie la valeur correspondante:

def getfile($k): .files[] | select(keys[] | .==$k) | .[$k]; 

Si jqtest contient les échantillons de données de la commande

$ jq -M ' 
def getfile($k): .files[] | select(keys[] | .==$k) | .[$k]; 
getfile("BLOCK1").SUBBLOCK1.akey1 
' jqtest 

Retours

"avalue1" 

Une autre approche consiste à utiliser une fonction pour convertir .files[] en une forme plus utile. par exemple.

$ jq -M ' 
def files: reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k]) ; 
files 
' jqtest 

cela renvoie une structure plus uniforme sans tableaux

{ 
    "BLOCK1": { 
    "SUBBLOCK1": { 
     "akey1": "avalue1", 
     "bkey1": "bvalue1", 
     "ckey1": "cvalue1" 
    }, 
    "dkey1": "dvalue1", 
    "key": "evalue1" 
    }, 
    "BLOCK-2": ... 

donc avec lui, vous pouvez écrire

files.BLOCK1.SUBBLOCK1 

pour obtenir

{ 
    "akey1": "avalue1", 
    "bkey1": "bvalue1", 
    "ckey1": "cvalue1" 
} 

Notez que JQ sera re- évaluer lefonctionà chaque utilisation de sorte que le formulaire ci-dessous peut être plus pratique:

files as $files 
| $files.BLOCK1.SUBBLOCK1 

Si vous trouvez cette représentation utile, vous pouvez sauter la fonction et au lieu juste de commencer votre filtre avec

.files = reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k]) 

par exemple

$ jq -M ' 
.files = reduce .files[] as $f ({}; ($f|keys[0]) as $k | .[$k] = $f[$k]) 
# more stuff goes here 
' jqtest 

qui convertit votre entrée à

{ 
    "files": { 
    "BLOCK1": { 
     "SUBBLOCK1": { 
     "akey1": "avalue1", 
     "bkey1": "bvalue1", 
     "ckey1": "cvalue1" 
     }, 
     "dkey1": "dvalue1", 
     "key": "evalue1" 
    }, 
    "BLOCK-2": { 
     "SUBBLOCK2": { 
     "akey2": "avalue2", 
     "bkey2": "bvalue2" 
     }, 
     "ckey2": "cvalue2", 
     "key": "dvalue2" 
    }, 
    "BLOCK-A": { 
     "SUBBLOCK2": { 
     "akey2": "avalue2", 
     "bkey2": "bvalue2" 
     }, 
     "ckey2": "cvalue2", 
     "key": "dvalue2" 
    } 
    }, 
    "NOBLOCK": "value", 
    "key": "NOBLOCKvalue" 
} 

prise tout ce que vous devez faire après plus facile

+0

Cela ressemble à une approche vraiment intéressante et je souhaite que je l'ai compris plus mais je ne peux pas passer la première déclaration. 'def getfile ($ k): .files [] | select (touches [] |. == $ k) | . [$ k]; 'me donne l'erreur suivante:' bash: erreur de syntaxe près du jeton inattendu '('' –

+0

try 'jq' def getfile ($ k): .fichiers [] | select (clés [] |. = = $ k) |. [$ k]; getfile ("BLOCK1"). SUBBLOCK1.akey1 'jqtest' ou envisager de placer le filtre dans un fichier 'filter.jq' et d'exécuter' jq -f filter.jq jqtest' – jq170727

+0

I J'ai ajouté les commandes explict aux exemples. – jq170727