Je souhaite fournir un fichier de configuration structuré qui soit aussi facile que possible à modifier pour un utilisateur non technique (malheureusement, ce doit être un fichier) et je voulais donc utiliser YAML. Je ne trouve cependant aucun moyen d'analyser cela à partir d'un script Unix Shell.
Mon cas d'utilisation peut être ou ne pas être tout à fait le même que ce que demandait cet article original, mais il est certainement similaire.
Je dois extraire certains YAML en tant que variables bash. Le YAML n'aura jamais plus d'un niveau.
YAML ressemble à ceci:
KEY: value
ANOTHER_KEY: another_value
OH_MY_SO_MANY_KEYS: yet_another_value
LAST_KEY: last_value
Sortie comme-a dis:
KEY="value"
ANOTHER_KEY="another_value"
OH_MY_SO_MANY_KEYS="yet_another_value"
LAST_KEY="last_value"
J'ai réalisé la sortie avec cette ligne:
sed -e 's/:[^:\/\/]/="/g;s/$/"/g;s/ *=/=/g' file.yaml > file.sh
s/:[^:\/\/]/="/g
trouve :
et le remplace par ="
tout en ignorant ://
(pour les URL).s/$/"/g
ajoute "
à la fin de chaque lignes/ *=/=/g
supprime tous les espaces avant =
Voici un analyseur syntaxique bash qui utilise sed et awk pour analyser des fichiers yaml simples:
function parse_yaml {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -ne "s|^\($s\):|\1|" \
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
Il comprend des fichiers tels que:
## global definitions
global:
debug: yes
verbose: no
debugging:
detailed: no
header: "debugging started"
## output
output:
file: "yes"
Qui, lors de l'analyse à l'aide de:
parse_yaml sample.yml
affichera:
global_debug="yes"
global_verbose="no"
global_debugging_detailed="no"
global_debugging_header="debugging started"
output_file="yes"
il comprend également les fichiers yaml, générés par Ruby qui peuvent inclure des symboles Ruby, tels que:
---
:global:
:debug: 'yes'
:verbose: 'no'
:debugging:
:detailed: 'no'
:header: debugging started
:output: 'yes'
et produira la même chose que dans l'exemple précédent.
utilisation typique dans un script est:
eval $(parse_yaml sample.yml)
parse_yaml accepte un argument de préfixe afin que les paramètres importés aient tous un préfixe commun (ce qui réduira le risque de collisions entre espaces de noms).
parse_yaml sample.yml "CONF_"
rendements:
CONF_global_debug="yes"
CONF_global_verbose="no"
CONF_global_debugging_detailed="no"
CONF_global_debugging_header="debugging started"
CONF_output_file="yes"
Notez que les paramètres précédents d'un fichier peuvent être référencés par des paramètres ultérieurs:
## global definitions
global:
debug: yes
verbose: no
debugging:
detailed: no
header: "debugging started"
## output
output:
debug: $global_debug
Une autre utilisation intéressante de Nice consiste à analyser d'abord un fichier de paramètres par défaut, puis les paramètres de l'utilisateur, ce qui fonctionne puisque ces derniers paramètres remplacent les premiers:
eval $(parse_yaml defaults.yml)
eval $(parse_yaml project.yml)
J'ai écrit shyaml
dans python pour les besoins de la requête YAML à partir de la ligne de commande Shell.
Vue d'ensemble:
$ pip install shyaml ## installation
Fichier YAML de l'exemple (avec fonctionnalités complexes):
$ cat <<EOF > test.yaml
name: "MyName !!"
subvalue:
how-much: 1.1
things:
- first
- second
- third
other-things: [a, b, c]
maintainer: "Valentin Lab"
description: |
Multiline description:
Line 1
Line 2
EOF
Requête de base:
$ cat test.yaml | shyaml get-value subvalue.maintainer
Valentin Lab
Requête en boucle plus complexe sur des valeurs complexes:
$ cat test.yaml | shyaml values-0 | \
while read -r -d $'\0' value; do
echo "RECEIVED: '$value'"
done
RECEIVED: '1.1'
RECEIVED: '- first
- second
- third'
RECEIVED: '2'
RECEIVED: 'Valentin Lab'
RECEIVED: 'Multiline description:
Line 1
Line 2'
Quelques points clés:
\0
la sortie complétée est disponible pour la manipulation d'entrée multiligne solide.subvalue.maintainer
est une clé valide).subvalue.things.-1
est le dernier élément de la séquence subvalue.things
.)Plus d’échantillons et de la documentation sont disponibles sur le page timideaml github ou sur le page timideaml PyPI .
Il est possible de passer un petit script à certains interprètes, comme Python. Un moyen facile de le faire en utilisant Ruby et sa bibliothèque YAML est le suivant:
$ Ruby_SCRIPT="data = YAML::load(STDIN.read); puts data['a']; puts data['b']"
$ echo -e '---\na: 1234\nb: 4321' | Ruby -ryaml -e "$Ruby_SCRIPT"
1234
4321
, oùdata
est un hachage (ou un tableau) avec les valeurs de yaml.
En prime, ça va analyser l'affaire de Jekyll tout va bien.
Ruby -ryaml -e "puts YAML::load(open(ARGV.first).read)['tags']" example.md
Etant donné que Python3 et PyYAML sont des dépendances assez faciles à respecter de nos jours, voici quelques solutions:
yaml() {
python3 -c "import yaml;print(yaml.load(open('$1'))$2)"
}
VALUE=$(yaml ~/my_yaml_file.yaml "['a_key']")
yq est un processeur YAML en ligne de commande léger et portable
Le but du projet est d’être le fichier jq ou sed des fichiers yaml.
( http://mikefarah.github.io/yq/ )
Par exemple (volé directement dans documentation ), à partir d'un exemple de fichier .yaml de:
---
bob:
item1:
cats: bananas
item2:
cats: apples
ensuite
yq r sample.yaml bob.*.cats
va sortir
- bananas
- apples
Difficile à dire car cela dépend de ce que vous voulez que l'analyseur extrait de votre document YAML. Pour des cas simples, vous pourrez peut-être utiliser grep
, cut
, awk
etc. Pour une analyse plus complexe, vous devrez utiliser une bibliothèque d'analyse complète, telle que celle de Python PyYAML ou YAML :: Perl .
Je viens d'écrire un analyseur que j'ai appelé Yay! (Yaml n'est pas Yamlesque!) qui analyse Yamlesque, un petit sous-ensemble de YAML. Donc, si vous cherchez un analyseur YAML 100% conforme pour Bash, alors ce n’est pas ça. Cependant, pour citer l'OP, si vous voulez n fichier de configuration structuré qui est aussi facile que possible à éditer par un utilisateur non technique qui ressemble à YAML, cela peut présenter un intérêt.
C'est inséré par la réponse précédente mais écrit des tableaux associatifs ( oui, il nécessite Bash 4.x ) au lieu de variables de base. Il le fait de manière à permettre l’analyse des données sans connaissance préalable des clés, ce qui permet d’écrire du code piloté par les données.
En plus des éléments de tableau clé/valeur, chaque tableau a un tableau keys
contenant une liste de noms de clés, un tableau children
contenant des noms de tableaux enfants et une clé parent
faisant référence à son parent.
This est un exemple de Yamlesque:
root_key1: this is value one
root_key2: "this is value two"
drink:
state: liquid
coffee:
best_served: hot
colour: brown
orange_juice:
best_served: cold
colour: orange
food:
state: solid
Apple_pie:
best_served: warm
root_key_3: this is value three
Here est un exemple montrant comment l'utiliser:
#!/bin/bash
# An example showing how to use Yay
. /usr/lib/yay
# helper to get array value at key
value() { eval echo \${$1[$2]}; }
# print a data collection
print_collection() {
for k in $(value $1 keys)
do
echo "$2$k = $(value $1 $k)"
done
for c in $(value $1 children)
do
echo -e "$2$c\n$2{"
print_collection $c " $2"
echo "$2}"
done
}
yay example
print_collection example
qui produit:
root_key1 = this is value one
root_key2 = this is value two
root_key_3 = this is value three
example_drink
{
state = liquid
example_coffee
{
best_served = hot
colour = brown
}
example_orange_juice
{
best_served = cold
colour = orange
}
}
example_food
{
state = solid
example_Apple_pie
{
best_served = warm
}
}
Et ici est l'analyseur:
yay_parse() {
# find input file
for f in "$1" "$1.yay" "$1.yml"
do
[[ -f "$f" ]] && input="$f" && break
done
[[ -z "$input" ]] && exit 1
# use given dataset prefix or imply from file name
[[ -n "$2" ]] && local prefix="$2" || {
local prefix=$(basename "$input"); prefix=${prefix%.*}
}
echo "declare -g -A $prefix;"
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -n -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$input" |
awk -F$fs '{
indent = length($1)/2;
key = $2;
value = $3;
# No prefix or parent for the top level (indent zero)
root_prefix = "'$prefix'_";
if (indent ==0 ) {
prefix = ""; parent_key = "'$prefix'";
} else {
prefix = root_prefix; parent_key = keys[indent-1];
}
keys[indent] = key;
# remove keys left behind if prior row was indented more than this row
for (i in keys) {if (i > indent) {delete keys[i]}}
if (length(value) > 0) {
# value
printf("%s%s[%s]=\"%s\";\n", prefix, parent_key , key, value);
printf("%s%s[keys]+=\" %s\";\n", prefix, parent_key , key);
} else {
# collection
printf("%s%s[children]+=\" %s%s\";\n", prefix, parent_key , root_prefix, key);
printf("declare -g -A %s%s;\n", root_prefix, key);
printf("%s%s[parent]=\"%s%s\";\n", root_prefix, key, prefix, parent_key);
}
}'
}
# helper to load yay data file
yay() { eval $(yay_parse "$@"); }
Il existe une documentation dans le fichier source lié et une brève explication de ce que fait le code est donnée ci-dessous.
La fonction yay_parse
localise d’abord le fichier input
ou quitte avec un état de sortie égal à 1. Elle détermine ensuite le dataset prefix
, spécifié explicitement ou dérivé du nom de fichier.
Il écrit des commandes bash
valides sur sa sortie standard qui, si elles sont exécutées, définissent des tableaux représentant le contenu du fichier de données en entrée. Le premier de ceux-ci définit le tableau de niveau supérieur:
echo "declare -g -A $prefix;"
Notez que les déclarations de tableau sont associatives (-A
), ce qui est une fonctionnalité de Bash version 4. Les déclarations sont également globales (-g
). Elles peuvent donc être exécutées dans une fonction mais être disponibles pour la portée globale, comme le yay
assistant:
yay() { eval $(yay_parse "$@"); }
Les données d'entrée sont traitées initialement avec sed
. Il supprime les lignes qui ne correspondent pas à la spécification de format Yamlesque avant de délimiter les champs Yamlesque valides avec un caractère ASCII séparateur de fichiers et de supprimer les guillemets doubles entourant le champ de valeur.
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -n -e "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$input" |
Les deux expressions sont similaires. elles ne diffèrent que par le fait que le premier choisit des valeurs entre guillemets, tandis que le second en choisit des non cotées.
Le séparateur de fichier (28/hex 12/octal 034) est utilisé car, en tant que caractère non imprimable, il est peu probable qu'il se trouve dans les données d'entrée.
Le résultat est acheminé dans awk
qui traite son entrée une ligne à la fois. Il utilise le caractère FS pour affecter chaque champ à une variable:
indent = length($1)/2;
key = $2;
value = $3;
Toutes les lignes ont un retrait (éventuellement zéro) et une clé, mais elles n’ont pas toutes une valeur. Il calcule un niveau de retrait pour la ligne divisant par deux la longueur du premier champ, qui contient les espaces blancs les plus grands. Les éléments de niveau supérieur sans retrait sont au niveau de retrait zéro.
Ensuite, il détermine ce que prefix
doit utiliser pour l’élément en cours. C'est ce qui est ajouté à un nom de clé pour créer un nom de tableau. Il y a un root_prefix
pour le tableau de niveau supérieur qui est défini comme le nom du fichier et un trait de soulignement:
root_prefix = "'$prefix'_";
if (indent ==0 ) {
prefix = ""; parent_key = "'$prefix'";
} else {
prefix = root_prefix; parent_key = keys[indent-1];
}
Le parent_key
est la clé au niveau de retrait au-dessus du niveau de retrait de la ligne en cours et représente la collection à laquelle la ligne en cours fait partie. Les paires clé/valeur de la collection seront stockées dans un tableau dont le nom correspond à la concaténation de prefix
et parent_key
.
Pour le niveau supérieur (niveau d'indentation zéro), le préfixe du jeu de données est utilisé comme clé parent. Il n'a donc pas de préfixe (il est défini sur ""
). Tous les autres tableaux ont le préfixe racine.
Ensuite, la clé actuelle est insérée dans un tableau (awk-internal) contenant les clés. Ce tableau persiste pendant toute la session awk et contient donc des clés insérées par des lignes précédentes. La clé est insérée dans le tableau en utilisant son retrait comme index du tableau.
keys[indent] = key;
Comme ce tableau contient des clés des lignes précédentes, toutes les clés ayant un niveau de retrait supérieur au niveau de retrait de la ligne actuelle sont supprimées:
for (i in keys) {if (i > indent) {delete keys[i]}}
Cela laisse le tableau de clés contenant la chaîne de clés de la racine au niveau d'indentation 0 à la ligne actuelle. Il supprime les clés périmées qui restent lorsque la ligne précédente était indentée plus profondément que la ligne actuelle.
La dernière section affiche les commandes bash
: une ligne d'entrée sans valeur commence un nouveau niveau de retrait (un collection en langage YAML) et une ligne d'entrée avec une valeur ajoute une clé au courant. collection.
Le nom de la collection est la concaténation des prefix
et parent_key
de la ligne en cours.
Quand une clé a une valeur, une clé avec cette valeur est assignée à la collection actuelle comme ceci:
printf("%s%s[%s]=\"%s\";\n", prefix, parent_key , key, value);
printf("%s%s[keys]+=\" %s\";\n", prefix, parent_key , key);
La première instruction renvoie la commande pour attribuer la valeur à un élément de tableau associatif nommé d'après la clé et la seconde génère la commande pour ajouter la clé à la liste keys
délimitée par des espaces de la collection:
<current_collection>[<key>]="<value>";
<current_collection>[keys]+=" <key>";
Quand une clé n'a pas de valeur, une nouvelle collection est lancée comme ceci:
printf("%s%s[children]+=\" %s%s\";\n", prefix, parent_key , root_prefix, key);
printf("declare -g -A %s%s;\n", root_prefix, key);
La première instruction génère la commande pour ajouter la nouvelle collection à la liste children
délimitée par des espaces de la collection en cours, et la seconde génère la commande pour déclarer un nouveau tableau associatif pour la nouvelle collection:
<current_collection>[children]+=" <new_collection>"
declare -g -A <new_collection>;
Toutes les sorties de yay_parse
peuvent être analysées en tant que commandes bash par les commandes intégrées bash eval
ou source
.
voici une version étendue de la réponse de Stefan Farestam:
function parse_yaml {
local prefix=$2
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @|tr @ '\034')
sed -ne "s|,$s\]$s\$|]|" \
-e ":1;s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s,$s\(.*\)$s\]|\1\2: [\3]\n\1 - \4|;t1" \
-e "s|^\($s\)\($w\)$s:$s\[$s\(.*\)$s\]|\1\2:\n\1 - \3|;p" $1 | \
sed -ne "s|,$s}$s\$|}|" \
-e ":1;s|^\($s\)-$s{$s\(.*\)$s,$s\($w\)$s:$s\(.*\)$s}|\1- {\2}\n\1 \3: \4|;t1" \
-e "s|^\($s\)-$s{$s\(.*\)$s}|\1-\n\1 \2|;p" | \
sed -ne "s|^\($s\):|\1|" \
-e "s|^\($s\)-$s[\"']\(.*\)[\"']$s\$|\1$fs$fs\2|p" \
-e "s|^\($s\)-$s\(.*\)$s\$|\1$fs$fs\2|p" \
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" | \
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]; idx[i]=0}}
if(length($2)== 0){ vname[indent]= ++idx[indent] };
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) { vn=(vn)(vname[i])("_")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, vname[indent], $3);
}
}'
}
Cette version prend en charge la notation -
et la notation courte pour les dictionnaires et les listes. L'entrée suivante:
global:
input:
- "main.c"
- "main.h"
flags: [ "-O3", "-fpic" ]
sample_input:
- { property1: value, property2: "value2" }
- { property1: "value3", property2: 'value 4' }
produit cette sortie:
global_input_1="main.c"
global_input_2="main.h"
global_flags_1="-O3"
global_flags_2="-fpic"
global_sample_input_1_property1="value"
global_sample_input_1_property2="value2"
global_sample_input_2_property1="value3"
global_sample_input_2_property2="value 4"
comme vous pouvez le voir, les éléments -
sont automatiquement numérotés afin d’obtenir des noms de variables différents pour chaque élément. Dans bash
il n'y a pas de tableaux multidimensionnels, c'est donc une façon de contourner le problème. Plusieurs niveaux sont pris en charge. Pour résoudre le problème des espaces insérés à la fin mentionnés par @briceburg, vous devez inclure les valeurs entre guillemets simples ou doubles. Toutefois, certaines limitations subsistent: L’expansion des dictionnaires et des listes peut produire des résultats erronés lorsque les valeurs contiennent des virgules. En outre, les structures plus complexes telles que les valeurs couvrant plusieurs lignes (telles que ssh-keys) ne sont pas (encore) prises en charge.
Quelques mots sur le code: La première commande sed
élargit la forme abrégée des dictionnaires { key: value, ...}
en régulière et les convertit en style plus simple yaml. Le deuxième appel sed
fait la même chose pour la notation courte de listes et convertit [ entry, ... ]
en une liste détaillée avec la notation -
. Le troisième appel sed
est l’appel original qui traitait les dictionnaires normaux, auquel il a maintenant été ajouté pour gérer les listes avec -
et les indentations. La partie awk
introduit un index pour chaque niveau d’indentation et l’augmente lorsque le nom de la variable est vide (c’est-à-dire lors du traitement d’une liste). La valeur actuelle des compteurs est utilisée à la place du nom vide vide. Quand on monte d'un niveau, les compteurs sont remis à zéro.
Edit: J'ai créé un référentiel github pour cela.
Une autre option consiste à convertir le fichier YAML en fichier JSON, puis à utiliser jq pour interagir avec la représentation JSON afin d’en extraire des informations ou de l’éditer.
J'ai écrit un script bash simple qui contient cette colle - voir projet Y2J sur GitHub
Perl -ne 'chomp; printf qq/%s="%s"\n/, split(/\s*:\s*/,$_,2)' file.yml > file.sh
Si vous avez python 2 et PyYAML, vous pouvez utiliser l'analyseur syntaxique que j'ai écrit et appelé parse_yaml.py . Certaines des choses plus simples qu'il fait sont de vous laisser choisir un préfixe (si vous avez plus d'un fichier avec des variables similaires) et de choisir une seule valeur dans un fichier yaml.
Par exemple, si vous avez ces fichiers yaml:
staging.yaml:
db:
type: sqllite
Host: 127.0.0.1
user: dev
password: password123
prod.yaml:
db:
type: postgres
Host: 10.0.50.100
user: postgres
password: password123
Vous pouvez charger les deux sans conflit.
$ eval $(python parse_yaml.py prod.yaml --prefix prod --cap)
$ eval $(python parse_yaml.py staging.yaml --prefix stg --cap)
$ echo $PROD_DB_Host
10.0.50.100
$ echo $STG_DB_Host
127.0.0.1
Et même choisir les valeurs que vous voulez.
$ prod_user=$(python parse_yaml.py prod.yaml --get db_user)
$ prod_port=$(python parse_yaml.py prod.yaml --get db_port --default 5432)
$ echo prod_user
postgres
$ echo prod_port
5432
Vous pouvez utiliser un équivalent de yq qui est écrit en golang:
./go-yg -yamlFile /home/user/dev/ansible-firefox/defaults/main.yml -key
firefox_version
résultats:
62.0.3
Je sais que cela est très spécifique, mais je pense que ma réponse pourrait être utile pour certains utilisateurs.
Si vous avez node
et npm
sur votre machine, vous pouvez utiliser js-yaml
.
Première installation:
npm i -g js-yaml
# or locally
npm i js-yaml
puis dans votre script bash
#!/bin/bash
js-yaml your-yaml-file.yml
Aussi, si vous utilisez jq
, vous pouvez faire quelque chose comme ça
#!/bin/bash
json="$(js-yaml your-yaml-file.yml)"
aproperty="$(jq '.apropery' <<< "$json")"
echo "$aproperty"
Parce que js-yaml
convertit un fichier yaml en un littéral de chaîne json. Vous pouvez ensuite utiliser la chaîne avec n’importe quel analyseur JSON de votre système Unix.
Si vous avez besoin d'une valeur unique, vous pouvez utiliser un outil qui convertit votre document YAML en JSON et le charge en jq
, par exemple yq
.
Contenu de sample.yaml:
---
bob:
item1:
cats: bananas
item2:
cats: apples
thing:
cats: oranges
Exemple:
$ yq -r '.bob["thing"]["cats"]' sample.yaml
oranges
Vous pouvez également envisager d'utiliser Grunt (Le gestionnaire de tâches JavaScript). Peut être facilement intégré à Shell. Il prend en charge la lecture des fichiers YAML (grunt.file.readYAML
) et JSON (grunt.file.readJSON
).
Ceci peut être réalisé en créant une tâche dans Gruntfile.js
(ou Gruntfile.coffee
), par exemple:
module.exports = function (grunt) {
grunt.registerTask('foo', ['load_yml']);
grunt.registerTask('load_yml', function () {
var data = grunt.file.readYAML('foo.yml');
Object.keys(data).forEach(function (g) {
// ... switch (g) { case 'my_key':
});
});
};
ensuite, à partir de Shell, exécutez simplement grunt foo
(vérifiez grunt --help
pour connaître les tâches disponibles).
De plus, vous pouvez implémenter exec:foo
tâches (grunt-exec
) avec des variables d'entrée transmises depuis votre tâche (foo: { cmd: 'echo bar <%= foo %>' }
) afin d'imprimer la sortie au format souhaité, puis de la canaliser vers une autre commande. .
Il existe également un outil similaire à Grunt, il s'appelle gulp avec un plugin supplémentaire gulp-yaml .
Installer via: npm install --save-dev gulp-yaml
Exemple d'utilisation:
var yaml = require('gulp-yaml');
gulp.src('./src/*.yml')
.pipe(yaml())
.pipe(gulp.dest('./dist/'))
gulp.src('./src/*.yml')
.pipe(yaml({ space: 2 }))
.pipe(gulp.dest('./dist/'))
gulp.src('./src/*.yml')
.pipe(yaml({ safe: true }))
.pipe(gulp.dest('./dist/'))
Pour plus d'options à traiter avec format YAML , cochez site YAML pour connaître les projets, bibliothèques et autres ressources disponibles qui peuvent vous aider à analyser ce format.
Autres outils:
analyse, lit et crée JSON