LINUX.ORG.RU

как переделать функцию, чтобы она загружала переменные?

 


0

3

cat some.yml

## global definitions
global:
  debug: yes
  verbose: no
  debugging:
    detailed: no
    header: "debugging started"

## output
output:
   file: "yes"
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);
      }
   }'
}

parse_yaml sample.yml

out:

global_debug="yes"
global_verbose="no"
global_debugging_detailed="no"
global_debugging_header="debugging started"
output_file="yes"

А как бы сделать так, чтобы внутри скрипта инициализировались эти переменны?

★★★★

YAML это язык разметки, как json например, или html, или маркдаун, там не должно быть никакой инициализации внутри. Но yaml-разметка может содержать, например, jinja2-темплейт (обычно это так используют, да) - сначала прогоняется шаблонизатор, который парсит переменные и выполняет подстановки, а дальше уже парсится сама YAML-разметка.

micronekodesu ★★★
()

Функцию переделывать не надо, надо переделать её вызов:

#!/bin/sh

  create_vars () {
    printf '%s\n' 'my_firstvar=1' 'my_secondvar="Vot Tak Tak"'
  } # create_vars

  echo 'Before:' ; set | grep '^my_'
  eval "$( create_vars )"
  echo 'After:'  ; set | grep '^my_'

ABW ★★★★★
()

Не парси yaml на баше. Возьми лучше питон.

unicorne
()

Выбери норм. средство для yml, например, perl

vitus@s1:/tmp$ ./t.pl 
debug: yes
file:  yes
vitus@s1:/tmp$ cat t.pl 
#!/usr/bin/perl -w
use strict;
use warnings;
use 5.010;

use YAML qw(LoadFile);

my $settings = LoadFile('some.yml');

print "debug: ", $settings->{global}->{debug} ,"\n";
print "file:  ", $settings->{output}->{file}, "\n";

vtVitus ★★★★★
()

Насколько я понял, на ваш вопрос никто не ответил. Но на самом деле ответ на него двоякий. Ибо значение что в кавычках — оно как должно быть записано в переменную? Если с самими кавычками, то это можно сделать просто и безопасно: printf -v $var '%s' «$value», где в var у вас будет global_debugging_header, а в $value "debugging started". Тем awk тут и не удобен, что это дополнительный внешний процесс и надо снова парсить key=value с разделителями из вывода. Потому проще отказаться вообще от awk. Ну как-то так:

declare -a idents subvar
declare -i ni i
sp='^([[:space:]]+)(.*)'

while IFS=: read var val; do
        [[ -z $var || $var = \#* ]] && continue
        if [[ $var =~ $sp ]]; then
                s=${BASH_REMATCH[1]}
                var=${BASH_REMATCH[2]}
        else
                s=
        fi
        while [[ ${#s} -le ${#idents[ni]} && ni -gt 0 ]]; do
                ni=ni-1
        done
        if [[ -z $val ]]; then
                subvar[ni]=$var
                if [[ ${#s} -gt ${idents[ni]} || ni -eq 0 ]]; then
                        ni+=1
                        idents[ni]=$s
                fi
        else
                val=${val# }
                v=
                for ((i=0; i<ni; i++)); do
                        v+=${v:+_}${subvar[i]}
                done
                v+=${v:+_}$var
                echo "$v=$val"
                printf -v $v "%s" "$val"
        fi
done

vodz ★★★★★
()
Ответ на: комментарий от ABW

Если б было всё так просто...

foo() {
        echo 'ls="$(ls)"'
}

eval "$(foo)"
echo "$ls"

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.