cClaude.rocks ☕ Le blog

[Nouvelles technologies, sciences et coups de gueule…]

Menu

underscore est une commande écrite en JavaScript (basée sur nodejs) permettant de formater du JSON, l’idée est ici de mettre en forme du code JSON et rendre des fichiers de configuration plus digestes, voir produire de la documentation.

underscore est destiné à être utilisé en ligne de commande.



Attention

La dernière version (0.2.19) date de 2016 et le code ne semble plus maintenu, malgré beaucoup de petits problèmes qui serait probablement simple à résoudre.

Ici, on se limitera à utiliser la commande underscore que pour reformater le code sans aucune modification.



Installation

underscore nécessite l’installation préalable de nodejs et s’installe à l’aide de npm :

sudo npm install -g underscore-cli

Tester l’installation avec l’aide de :

underscore help


Usage

Exemples a partir du même code JSON


Avec jq

echo '{"@file":"post/2023/09/28.formater-json-underscore.md","@is-published":false,"@sha256sum":"69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md","@tags":["javascript","json","$npm","technologies","$underscore","cli"],"@udates":null,"@uri":null,"autoheader":"technologies","cdate":"2023-09-28","date":"2023-09-28","status":"draft","tags":"javascript, json, $npm, technologies, $underscore, cli","title":"🐚 Formater du JSON avec underscore","type":"post","wikis":""}' |
jq .
  • Résultat avec jq
    {
      "@file": "post/2023/09/28.formater-json-underscore.md",
      "@is-published": false,
      "@sha256sum": "69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md",
      "@tags": [
        "javascript",
        "json",
        "$npm",
        "technologies",
        "$underscore",
        "cli"
      ],
      "@udates": null,
      "@uri": null,
      "autoheader": "technologies",
      "cdate": "2023-09-28",
      "date": "2023-09-28",
      "status": "draft",
      "tags": "javascript, json, $npm, technologies, $underscore, cli",
      "title": "🐚 Formater du JSON avec underscore",
      "type": "post",
      "wikis": ""
    }
    

Avec underscore et l’option pretty

Un usage destiné à la lecture seule (par un humain) car il ne produit pas un code JSON valide.

echo '{"@file":"post/2023/09/28.formater-json-underscore.md","@is-published":false,"@sha256sum":"69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md","@tags":["javascript","json","$npm","technologies","$underscore","cli"],"@udates":null,"@uri":null,"autoheader":"technologies","cdate":"2023-09-28","date":"2023-09-28","status":"draft","tags":"javascript, json, $npm, technologies, $underscore, cli","title":"🐚 Formatter du JSON avec underscore","type":"post","wikis":""}' |
underscore pretty

on a un résultat (en couleur, non reproduit ici) :

  • Résultat avec underscore pretty
    {
      "@file": "post/2023/09/28.formater-json-underscore.md",
      "@is-published": false,
      "@sha256sum": "69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md",
      "@tags": ["javascript", "json", "$npm", "technologies", "$underscore", "cli"],
      "@udates": null,
      "@uri": null,
      autoheader: "technologies",
      cdate: "2023-09-28",
      date: "2023-09-28",
      status: "draft",
      tags: "javascript, json, $npm, technologies, $underscore, cli",
      title: "🐚 Formater du JSON avec underscore",
      type: "post",
      wikis: ""
    }
    

Avec underscore et l’option print

L’option print permet de reformater le code JSON sans pour autant casser le standard.

echo '{"@file":"post/2023/09/28.formater-json-underscore.md","@is-published":false,"@sha256sum":"69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md","@tags":["javascript","json","$npm","technologies","$underscore","cli"],"@udates":null,"@uri":null,"autoheader":"technologies","cdate":"2023-09-28","date":"2023-09-28","status":"draft","tags":"javascript, json, $npm, technologies, $underscore, cli","title":"🐚 Formater du JSON avec underscore","type":"post","wikis":""}' |
underscore print
  • Résultat avec underscore print
    {
      "@file": "post/2023/09/28.formater-json-underscore.md",
      "@is-published": false,
      "@sha256sum": "69a8719bb512080aaeab5310f96b244bf1eb9bd7dc0b4969d0018df7f88e5ba1  post/2023/09/28.formater-json-underscore.md",
      "@tags": ["javascript", "json", "$npm", "technologies", "$underscore", "cli"],
      "@udates": null,
      "@uri": null,
      "autoheader": "technologies",
      "cdate": "2023-09-28",
      "date": "2023-09-28",
      "status": "draft",
      "tags": "javascript, json, $npm, technologies, $underscore, cli",
      "title": "🐚 Formater du JSON avec underscore",
      "type": "post",
      "wikis": ""
    }
    


Petite optimisation

Dans le cas d’un tableau vide underscore, produit une sortie pas géniale; insérons un tableau vide dans notre exemple :

echo '{"str":"On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne","array1":[],"array2":[]}' | jq .

Avec *jq, on a :

{
  "str": "On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne",
  "array1": [],
  "array2": []
}

Si on ajoute le traitement de la commande underscore

echo '{"str":"On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne","array1":[],"array2":[]}' | jq . |
underscore print

on a :

{
  "str": "On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne",
  "array1": [ ],
  "array2": [ ]
}

Les affichages "array1": [ ], et "array2": [ ] ne sont pas très heureux, je vous propose donc un petit coup de sed pour corriger cela :

Comme on ne veut pas modifier le contenu de la chaîne de caractère, il nous faut nous appuyer sur les sauts de ligne pour s’assurer qu’on est pas en train de modifier le contenu d’une chaîne.

On va devoir traiter deux cas, celui avec la virgule et celui sans (fin d’objet). On peut faire cela à l’aide de deux expressions régulières, comme suit :

echo '{"str":"On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne","array1":[],"array2":[]}' | jq . |
underscore print | sed -e 's,: \[ \]$,: [],g' -e 's|: \[ \],$|: [],|g'

Ou mieux à l’aide d’une expression régulière étendue :

echo '{"str":"On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne","array1":[],"array2":[]}' | jq . |
underscore print | sed -E 's|^(.*): \[ \]([,]{0,1})$|\1: []\2|g'

Et voilà…

{
  "str": "On veut pas de : [ ] - On veut pas de : [ ] - une très longue ligne",
  "array1": [],
  "array2": []
}

Limitations

Dans le cas où l’objet tiens sur une seule ligne, cette astuce ne fonctionnera pas, mais le code JSON reste valide.

echo '{"str":"On veut pas de : [ ]","array1":[],"array2":[]}' | jq . |
underscore print | sed -E 's|^(.*): \[ \]([,]{0,1})$|\1: []\2|g'
{ "str": "On veut pas de : [ ]", "array1": [ ], "array2": [ ] }

L’expression régulière (« regexp ») du cas général, me semble inatteignable ; mais je prends la solution. À moins que quelqu’un ne reprenne le code d'underscore-cli.


Explications

Détaillons la commande sed :

sed -E 's|^(.*): \[ \]([,]{0,1})$|\1: []\2|g'

L'option -E est là pour indiquer que l'on va utiliser les expressions régulières étendues.

L'expression régulière 's|^(.*): \[ \]([,]{0,1})$|\1: []\2|g' se décompose comme suit:

  • s - Commande pour recherche et remplace ("search and replace")
  • | - Séparateur de champ
  • ^(.*): \[ \]([,]{0,1})$ - Ce qu'on recherche
  • | - Séparateur de champ
  • \1: []\2 - Par quoi on remplace
  • | - Séparateur de champ
  • g - Commande pour indiquer de faire le traitement sur tout le fichier ("global")

Généralement, on utilise la virgule comme séparateur de champ, mais en réalité sed permet d'utilisé n'importe quel charactère pour peut qu'on utilise toujours le meme dans l'expression. Comme nous devons recherche des virgules dans ce cas, on utilise un autre caractère ici: |.

Ce qu'on recherche: ^(.*): \[ \]([,]{0,1})$

  • ^ - Indique qu'on commence au début de la ligne.
  • (.*) - Les parenthèses indiquent une capture (en gros on va mémorisé ce qui est capturer par cette expression) : .* veut litérallement dire n'importe quoi (plus précisémenent . n'importe quel caractère, * autant de fois que possible.
  • : \[ \] - Ici c'est vraiment ce qu'on cherche à remplacer, techniquement il s'agit de : [ ] mais les crochets ayant une signification particulière on doit les échapper en ajoutant le caractère '' devant.
  • ([,]{0,1}) - Les parenthèses indique une capture, et on recherche [,]{0,1}, ce qui veut dire "on cherche le caractère virgule, 0 ou 1 fois.
  • $ - Indique qu'on finit en fin de ligne.

Par quoi on remplace: \1: []\2

  • \1 - Ceci référence la première capture (le début de la ligne)
  • : [] - C'est littéralement la chaîne qu'on souhaite changé
  • \2 - Ceci référence la seconde capture (on remet ou pas une virgule)


Liens

ᦿ


ℹ 2006 - 2023 | 🏠 Accueil du domaine | 🏡 Accueil du blog