¿Cómo puedo analizar un archivo YAML desde un script de shell de Linux?

Resuelto yazz.com asked hace 13 años • 25 respuestas

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.

yazz.com avatar Feb 16 '11 16:02 yazz.com
Aceptado

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)
Stefan Farestam avatar Jan 17 '2014 15:01 Stefan Farestam

He escrito shyamlen 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...
  • \0La 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.maintaineres una clave válida).
  • el acceso por índice se proporciona a las secuencias (es decir, subvalue.things.-1es el último elemento de la subvalue.thingssecuencia).
  • 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 .

vaab avatar Feb 27 '2013 13:02 vaab