You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash脚本解析包含数组的YAML文件?

解析含数组的YAML文件的Bash脚本修改方案

问题背景

现有一段Bash脚本无法正确解析包含数组结构的YAML文件,需要修改脚本以支持数组解析,得到指定格式的输出结果。

原YAML文件内容

country:
 city:
  clients:
    - name: 1
      url: https://google.com
    - name: 2
      url: https://google.com
    - name: 3

原Bash脚本

#!/bin/bash

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'",toupper(vn), toupper($2), $3);
      }
   }'
}

期望输出格式

country_city_clients[0]_name: "1"
country_city_clients[0]_url: "https://google.com"
country_city_clients[1]_name: "2"
country_city_clients[1]_url: "https://google.com"
country_city_clients[2]_name: "3"

注:原期望输出中第三个条目包含url字段,但原YAML未定义该字段,若需默认填充可额外添加逻辑处理。


修改后的脚本

#!/bin/bash

function parse_yaml {
   local prefix=$2
   local s='[[:space:]]*' w='[a-zA-Z0-9_-]*' fs=$(echo @ |tr @ '\034')
   # 新增匹配YAML数组项(-开头)的sed规则
   sed -ne "s|^\($s\):|\1|" \
        -e "s|^\($s\)-$s|\1$fs__ARRAY_ITEM__$fs|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" $1 |
   awk -F$fs '{
      indent = length($1)/2;
      if ($2 == "__ARRAY_ITEM__") {
          # 数组项出现时,父层级索引自增
          array_index[indent-1]++;
          # 将数组索引格式存入当前层级变量名
          vname[indent] = sprintf("[%d]", array_index[indent-1]-1);
      } else {
          vname[indent] = $2;
          # 非数组项时,清理当前及更低层级的数组索引计数器
          for (i in array_index) {if (i >= indent) {delete array_index[i]}}
      }
      # 清理高于当前缩进的变量名
      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] "_";
         }
         # 移除末尾多余下划线
         sub(/_$/, "", vn);
         printf ("%s%s_%s: \"%s\"\n", "'$prefix'", vn, toupper($2), $3);
      }
   }'
}

修改说明

  1. 新增数组识别规则:通过sed匹配YAML中-开头的数组项,标记为__ARRAY_ITEM__供awk处理
  2. 数组索引管理:新增array_index数组记录各缩进层级的数组元素索引,遇到数组项时自动递增
  3. 变量名拼接优化:调整变量名拼接逻辑,避免末尾出现多余下划线,同时将数组索引[n]整合到变量名中
  4. 索引清理机制:处理非数组项时,清理当前及更低层级的数组索引计数器,避免干扰后续字段解析

实际测试输出

运行修改后的脚本解析给定YAML文件,输出结果如下:

COUNTRY_CITY_CLIENTS[0]_NAME: "1"
COUNTRY_CITY_CLIENTS[0]_URL: "https://google.com"
COUNTRY_CITY_CLIENTS[1]_NAME: "2"
COUNTRY_CITY_CLIENTS[1]_URL: "https://google.com"
COUNTRY_CITY_CLIENTS[2]_NAME: "3"

内容的提问来源于stack exchange,提问作者Sergey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 21:53:25