1
votes

Bash: Comment ajouter une valeur de tableau à JSON?

Je mets en place un script bash pour analyser une URL dans ses composants. Je suis bloqué en essayant de comprendre comment ajouter une valeur de tableau à une clé dans un corps JSON.

Tentative d'approche:

J'ai analysé l'URL suivante: https://bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders

Le chemin de cette URL est:

URL_PATH: v2020 / folders / 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 / folders

Le tableau de parties de chemin de cette URL utilise

  HREF: https://bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_PROTOCOL: https://
  URL_SCHEME: https
  URL: bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_HOST: bar.foo.com
  URL_PATH: v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders
  URL_PATH_PARTS [4]: v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders

  URL_COMPONENTS:
{
  "protocol": "https://",
  "scheme": "https",
  "url": "bar.foo.com/v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "host": "bar.foo.com",
  "path": "v2020/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "parts": "[v2020 folders 8d55e749-bbd7-e811-9c19-3ca82a1e3f41 folders]"
}


4 commentaires

Pourquoi utilisez-vous à la fois sed et jq ? Si vous utilisez jq pour manipuler JSON, vous ne devriez avoir absolument aucune raison d'utiliser sed dans le même but (auquel il est beaucoup moins adapté).


(De plus, notez que lorsque vous utilisez bash spécifiquement, il a un support regex intégré, qui est généralement beaucoup plus rapide que de lancer une commande externe comme sed ; voir BashFAQ # 100 pour une introduction générale à la manipulation de chaînes natives dans bash).


Utilisez des substitutions de variables au lieu d'exécuter des commandes dans des sous-shells. Par exemple; au lieu de URL_HOST = "$ (echo $ URL_HOSTPORT | sed -e 's,:. * , g')" , utilisez URL_HOST = $ {URL_HOST_PORT%: *} .


Voir github.com/stedolan/jq/issues/537#issuecomment-51635126, à partir de 2014, montrant comment tout faire de manière native dans jq seul.


3 Réponses :


1
votes

Code actuel utilisant: \ "parts \": \ "[$ {URL_PATH_PARTS [@]}] \" pour le chemin. La solution possible consiste à parcourir les éléments, en créant une chaîne combinée avec des guillemets et un séparateur ','

PP=
for P1 in "${URL_PATH_PARTS[@]}" ; do
  # Add ',' unless this is first item
  [ "$PP" ] && PP="$PP, "
  PP=$PP\"$P1\"
done

Le remplacement IN (composants d'URL)

\ "parts \": \ "[$ {URL_PATH_PARTS [@]}] \"

Avec

\ "parts \": [$ PP]


2 commentaires

Il y a beaucoup plus à générer correctement JSON valide que d'ajouter simplement des virgules (et ne pas citer les extensions de votre tableau signifie qu'un URI qui contient des caractères génériques peut injecter des noms de fichiers du répertoire actuel dans votre résultat).


@CharlesDuffy merci d'avoir indiqué l'expansion du tableau involontaire dans l'instruction "for P1".



2
votes

Ne vous embêtez pas avec le tableau. Utilisez la substitution de variable:

SLASHES="${URL_PATH//[^\/]}/"       # Append slash to avoid fence-post error.
echo "  URL_PATH_PARTS [${#SLASHES}]: ${URL_PATH//\// }"

...

 \"parts\": [ \"${URL_PATH//\//\", \"}\" ] \  # Replace slashes with '", "'

Vous pouvez également supprimer la variable intermédiaire "URL_PATH_PARTS" (et perdre une certaine lisibilité):

URL_PATH_PARTS=${URL_PATH//\/ }         # Replace slashes with spaces
SPACES="${URL_PATH_PARTS//[^ ]} "       # Append space to avoid fence-post error.
echo "  URL_PATH_PARTS [${#SPACES}]: ${URL_PATH_PARTS}"

...

 \"parts\": [ \"${URL_PATH_PARTS// /\", \"}\" ] \  # Replace spaces with '", "'


0 commentaires

1
votes

Merci @CharlesDuffy, @ dash-o, @AndrewVickers

J'ai essayé toutes vos suggestions.

L'approche suggérée que j'ai adoptée était joelpurra / jq-hopkok

Code Bash

{
  "value": "https://apiuatna11.springcm.com/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
  "valid": true,
  "scheme": {
    "value": "https",
    "valid": true
  },
  "domain": {
    "value": "apiuatna11.springcm.com",
    "components": [
      "apiuatna11.springcm.com",
      "springcm.com",
      "com"
    ],
    "tld": "com",
    "valid": true
  },
  "port": {
    "value": null,
    "separator": false,
    "valid": true
  },
  "path": {
    "value": "/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders",
    "components": [
      "v201411",
      "folders",
      "8d55e749-bbd7-e811-9c19-3ca82a1e3f41",
      "folders"
    ],
    "valid": true
  },
  "query": {
    "value": null,
    "separator": false,
    "components": [],
    "valid": true
  },
  "fragment": {
    "value": null,
    "separator": false,
    "valid": true
  }
}

Réponse JSON h3>
#!/usr/bin/env bash

URL='"https://apiuatna11.springcm.com/v201411/folders/8d55e749-bbd7-e811-9c19-3ca82a1e3f41/folders"'

# URL to components
echo $URL | ./jq-hopkok/src/url/to-components.sh


0 commentaires