如何将YAML的子集转换为关联数组的索引数组? [英] How to convert a subset of YAML into an indexed array of associative arrays?

查看:88
本文介绍了如何将YAML的子集转换为关联数组的索引数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Linux上使用Bash 4.3.

I am using Bash 4.3 on linux.

我有一个简单的YAML风格的数据文件:

I have this simple YAML-esque data file:

products:
  product1:
    name: "Product one"
    price: 100
  product2:
    name: "Product two"
    price: 200
myList:
  - one
  - two

我需要一个shell函数,以上面的YAML文件作为输入,可以生成然后执行以下Bash代码:

And I need a shell function that, taking the above YAML file as input, can generate and then execute the below Bash code:

unset products product1  product2

# declare the associative arrays
declare -A product1
declare -A product2


# define the data
product1=(
  [name]="Product 1"
  [price]=100
)

product2=(
  [name]="Product 2"
  [price]=200
)

myList=(one two)

# declare the arrays which will contain the names of our associative arrays
products=(product1 product2)

一旦有了这个出色的功能,我将使用YAML文件自动生成数据,以用于我的自定义CMS模板系统中,如下所示:

Once I have this wonderful function, I will use the YAML files to automatically generate data, to be used in my custom CMS templating system like so:

{{#foreach product in products}}
  <h3>{{product.name | uppercase}}</h3>
  * {{product.price | money_with_currency £ GBP | without_trailing_zeros}}
{{/foreach}}

我已经尝试了各种YAML解析器,但是没有找到可以生成我需要的关联数组的解析器,而有些根本不起作用(至少对我而言):

I have already tried various YAML parsers, but have not found one that can generate the associative arrays that I need, and some simply didn't work at all (for me, at least):

  • https://github.com/ArtBIT/bash-yaml
  • https://github.com/luodongseu/shyaml
  • https://github.com/binaryphile/y2s
  • https://github.com/Hashfyre/yamlparser
  • https://github.com/ash-shell/yaml-parse
  • https://github.com/jasperes/bash-yaml
  • https://github.com/mrbaseman/parse_yaml
  • https://github.com/azohra/yaml.sh
  • https://github.com/Minlison/yaml-parser
  • https://gist.github.com/pkuczynski/8665367

据我了解,其中大多数使用它们会生成类似product_product1_name="foo"的东西:(

Most of these, as far as I understand their usage generate things like product_product1_name="foo" :(

推荐答案

yaml.sh 您在问题中链接的,是一个出奇的好解析器.将其输出转换为所需的格式比执行其他任何操作都容易得多.

yaml.sh, which you linked in the question, is a surprisingly good parser. It's a lot easier to convert its output into the format you need than to do anything else.

cleanupValue() {
  local result
  case $1 in
    '"'*'"') result=${1#'"'}; result=${result%'"'} ;;
    "["*"]") result=${1#'['}; result=${result%']'} ;;
    *)       result=$1
  esac
  printf '%s\n' "$result"
}

record_data() {
  local key value="$(cleanupValue "$1")"; shift
  while (( $# >= 2 )); do
    key=$(cleanupValue "$2")
    if (( $# > 2 )); then
      declare -g -a "$1" || continue
      declare -g -A "_${1}__seen" || continue
      local -n __array="$1"
      local -n __seen_array="_${1}__seen"
      if ! [[ ${__seen_array[$key]} ]]; then
        __seen_array[$key]=1
        __array+=( "$key" )
      fi
      unset -n __seen_array
    else
      declare -g -A "$1"    || continue  # "continue" to skip invalid variable names
      local -n __array="$1" || continue
      __array[$key]=$value
    fi
    unset -n __array
    shift
  done
}

while IFS='=' read -r key value; do
  IFS=. read -r -a key_pieces <<<"$key"
  record_data "$value" "${key_pieces[@]}"
done < <(ysh -f your.yml)

# demonstrate results
declare -p products product1 product2 myList

...作为输出发出:

...emits as output:

declare -a products=([0]="product1" [1]="product2")
declare -A product1=([price]="100" [name]="Product one" )
declare -A product2=([price]="200" [name]="Product two" )
declare -A myList=([1]="two" [0]="one" )

这篇关于如何将YAML的子集转换为关联数组的索引数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆