¿Cómo puedo analizar un archivo YAML desde un script de shell de Linux?
Deseo proporcionar un archivo de configuración estructurado que sea lo más fácil de editar posible para un usuario no técnico (desafortunadamente tiene que ser un archivo) y por eso quería usar YAML. Sin embargo, no puedo encontrar ninguna forma de analizar esto desde un script de shell de Unix.
Aquí hay un analizador solo de bash que aprovecha sed y awk para analizar archivos 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);
}
}'
}
Entiende archivos como:
## global definitions
global:
debug: yes
verbose: no
debugging:
detailed: no
header: "debugging started"
## output
output:
file: "yes"
Que, cuando se analiza usando:
parse_yaml sample.yml
generará:
global_debug="yes"
global_verbose="no"
global_debugging_detailed="no"
global_debugging_header="debugging started"
output_file="yes"
también comprende archivos yaml, generados por Ruby, que pueden incluir símbolos de Ruby, como:
---
:global:
:debug: 'yes'
:verbose: 'no'
:debugging:
:detailed: 'no'
:header: debugging started
:output: 'yes'
y generará el mismo resultado que en el ejemplo anterior.
El uso típico dentro de un script es:
eval $(parse_yaml sample.yml)
parse_yaml acepta un argumento de prefijo para que todas las configuraciones importadas tengan un prefijo común (lo que reducirá el riesgo de colisiones de espacios de nombres).
parse_yaml sample.yml "CONF_"
rendimientos:
CONF_global_debug="yes"
CONF_global_verbose="no"
CONF_global_debugging_detailed="no"
CONF_global_debugging_header="debugging started"
CONF_output_file="yes"
Tenga en cuenta que las configuraciones posteriores de un archivo pueden hacer referencia a configuraciones posteriores:
## global definitions
global:
debug: yes
verbose: no
debugging:
detailed: no
header: "debugging started"
## output
output:
debug: $global_debug
Otro buen uso es analizar primero un archivo predeterminado y luego la configuración del usuario, lo cual funciona ya que la última configuración anula las primeras:
eval $(parse_yaml defaults.yml)
eval $(parse_yaml project.yml)
He escrito shyaml
en Python para las necesidades de consultas YAML desde la línea de comando del shell.
Descripción general:
$ pip install shyaml ## installation
Archivo YAML de ejemplo (con características complejas):
$ 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
Consulta básica:
$ cat test.yaml | shyaml get-value subvalue.maintainer
Valentin Lab
Consulta en bucle más compleja sobre valores complejos:
$ 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'
Algunos puntos clave:
- todos los tipos YAML y rarezas de sintaxis se manejan correctamente, como cadenas multilínea, entre comillas, secuencias en línea...
\0
La salida acolchada está disponible para una manipulación sólida de entradas multilínea.- Notación de puntos simple para seleccionar subvalores (es decir,
subvalue.maintainer
es una clave válida). - el acceso por índice se proporciona a las secuencias (es decir,
subvalue.things.-1
es el último elemento de lasubvalue.things
secuencia). - acceso a todos los elementos de secuencia/estructuras de una sola vez para su uso en bucles bash.
- puede generar una subparte completa de un archivo YAML como ... YAML, que se combinan bien para manipulaciones posteriores con shyaml.
Hay más ejemplos y documentación disponibles en la página de shyaml github o en la página de shyaml PyPI .