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

如何将多层YAML/JSON递归解析为Bash变量?

实现YAML转层级命名的Bash变量

你的example.yaml文件内容如下:

networks:
  net:
    driver: overlay
dockerfiles:
  nodeapp: |
    FROM node:18-alpine
    WORKDIR /$NAME
services:
  registry:
    image: registry:2
    ports:
      - "5000:5000"
      - "337:337"
  pinger:
    build:
      context: .
      dockerfile: nodeapp
    deploy:
      replicas: 3

目前你能通过yq转JSON后用jq生成顶层变量,但无法递归生成层级命名的变量(比如希望echo $services_pinger_build_dockerfile能输出nodeapp),以下是实现方法:

解决方案

使用jq的递归遍历+路径追踪功能,生成下划线连接的层级变量名,最终输出可被eval执行的赋值语句:

eval $(yq e example.yaml -j | jq -r '
  def path_to_var:
    .path | map(tostring) | join("_");
  def walk_vars:
    if type == "object" then
      .[] | walk_vars
    elif type == "array" then
      to_entries[] | (.key | tostring) as $idx | .value | setpath([$idx]; .) | walk_vars
    else
      [path_to_var, (tostring | @sh)] | join("=")
    end;
  walk_vars
')

执行后即可调用层级变量:

echo $services_pinger_build_dockerfile
# 输出:nodeapp

echo $networks_net_driver
# 输出:overlay

echo $services_registry_ports_0
# 输出:5000:5000

命令说明

  1. path_to_var函数:将节点的路径数组(如["services", "pinger", "build", "dockerfile"])转为下划线连接的变量名;
  2. walk_vars函数:
    • 遇到对象时递归遍历所有子节点;
    • 遇到数组时将索引加入路径,生成带索引的变量名(如services_registry_ports_0);
    • 遇到基础类型(字符串、数字等)时,生成符合Bash语法的赋值语句,@sh用于确保字符串值被正确转义;
  3. eval执行:批量运行jq输出的赋值语句,将变量导入当前Shell环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:42:11