Comment supprimer les guillemets pour les clés JSON dans la chaîne JSON en utilisant l'expression régulière dans JQ

2020-06-29 json regex jq

Essayer de convertir la charge utile json en graphql et avoir des problèmes. J'ai besoin de convertir une chaîne comme

"{
  \"entity\":{
    \"id\":\"7fbe7e65-0f01-4934-a2a9-dcc6d81a5b95\",
    \"type\":\"Products\",
    \"status\":\"pending\",
    \"services\":[
      {
        \"id\":\"1e05737e-754b-4d19-b872-5a0135d99cf4\",
        \"type\":\"Services\",
        \"status\":\"active\"
      },{
        \"id\":\"2238fe75-3d1a-4768-8464-be7d48037215\",
        \"type\":\"Services\",
        \"status\":\"active\"
      }
    ]
  }
}"

à la chaîne où aucun guillemet pour les clés:

"{
  entity:{
    id:\"7fbe7e65-0f01-4934-a2a9-dcc6d81a5b95\",
    type:\"Products\",
    status:\"pending\",
    services:[
      {
        id:\"1e05737e-754b-4d19-b872-5a0135d99cf4\",
        type:\"Services\",
        status:\"active\"
      },{
        id:\"2238fe75-3d1a-4768-8464-be7d48037215\",
        type:\"Services\",
        status:\"active\"
      }
    ]
  }
}"

J'ai réussi à remplacer uniquement toutes les citations, mais comment supprimer des citations uniquement pour les clés? Veuillez noter que j'ai ajouté \ n ici juste pour une meilleure compréhension. Normalement, j'ai le json sous forme de chaîne sans \ n.

Answers

L'entrée illustrative est une forme de JSON échappé, il serait donc probablement logique de commencer par la déséchapper. En utilisant votre exemple, je vais montrer comment cela peut être fait de trois manières, mais décider de la méthode qui convient dépendra de la façon dont le JSON d'échappement a été généré.

Je proposerai ensuite quelques transformations supplémentaires qui pourront être utiles sur la route de graphQL.

Pour plus de clarté, j'ai copié le JSON échappé dans un fichier, escaped.json:

$ cat escaped.json
"{
  \"entity\":{
    \"id\":\"7fbe7e65-0f01-4934-a2a9-dcc6d81a5b95\",
    \"type\":\"Products\",
    \"status\":\"pending\",
    \"services\":[
      {
        \"id\":\"1e05737e-754b-4d19-b872-5a0135d99cf4\",
        \"type\":\"Services\",
        \"status\":\"active\"
      },{
        \"id\":\"2238fe75-3d1a-4768-8464-be7d48037215\",
        \"type\":\"Services\",
        \"status\":\"active\"
      }
    ]
  }
}"

Utilisation de jq pour "décompresser" le JSON échappé

Une possibilité serait d'utiliser jj's fromjson :

jq fromjson <<< $(cat escaped.json)

ou

tr -d '\n' < escaped.json | jq fromjson 

Par souci de concision, envisagez plutôt:

    $ jq 'fromjson|length' <<< $(cat escaped.json)
    1

Utiliser eval pour "déséchapper" le JSON échappé

Dans ce qui suit, je vais supposer un shell bash ou similaire à bash, mais le même genre de chose peut être fait dans d'autres shells.

Pour montrer que eval produit un JSON valide, j'ai canalisé le résultat en jq length :

$ eval echo $(cat escaped.json) | jq length
1

JSON échappé dans une variable

Si la variable shell, $ x, contient le JSON échappé, nous pouvons également utiliser eval . Considérez, par exemple:

$ jq length <<< $x
287
$ jq length <<< $(eval printf $x)
1

En route vers graphQL

En utilisant le JSON d'échappement original, la combinaison suivante de jq et sed produit le résultat illustré ci-dessous.

jq 'fromjson 
    | walk(if type == "array" or type == "object" then . else null end)' <<< $(cat escaped.json) |
  sed '/"/{s/"//g; s/: null.*//;}'

Production

{
  entity: {
    id
    type
    status
    services: [
      {
        id
        type
        status
      },
      {
        id
        type
        status
      }
    ]
  }
}

Pour supprimer les guillemets autour des clés, les éléments suivants peuvent suffire.

tr -d '\n' < escaped.json |
  jq fromjson |
  sed '/^ *".*": /{s/"//; s/": /: /;}'

Avec l'exemple d'entrée, cela produit:

{
  entity: {
    id: "7fbe7e65-0f01-4934-a2a9-dcc6d81a5b95",
    type: "Products",
    status: "pending",
    services: [
      {
        id: "1e05737e-754b-4d19-b872-5a0135d99cf4",
        type: "Services",
        status: "active"
      },
      {
        id: "2238fe75-3d1a-4768-8464-be7d48037215",
        type: "Services",
        status: "active"
      }
    ]
  }
}

Related