使用yq提取YAML属性键时Bash循环解析异常的解决方法
YAML多键解析异常的Bash脚本解决方案
问题背景
现有目标YAML文件config.yaml:
attr_keys: x: y: [1, 2, 3] z: 7
需编写Bash脚本遍历attr_keys.x下的所有键。使用yq v4.34.1编写的初始脚本在attr_keys.x仅含单个键时输出正常,但存在多个键时,所有键被合并为单个字符串,导致遍历异常。
初始脚本及问题
初始脚本:
parameters_keys=$(yq e ".attr_keys.x | keys | .[] " config.yaml) for parameter_key in "${parameters_keys[@]}" do echo "Key: $parameter_key" done
- 单键场景(仅
y):输出符合预期:Key: y - 多键场景:实际输出异常:
预期输出应为:Key: y zKey: y Key: z
有效解决方案
方案1:用readarray直接读取为数组
利用Bash的readarray(或mapfile)命令,将yq输出的每一行直接存入数组:
readarray -t parameters_keys < <(yq e ".attr_keys.x | keys | .[]" config.yaml) for parameter_key in "${parameters_keys[@]}" do echo "Key: $parameter_key" done
说明:readarray -t会将输入的每一行作为数组的一个独立元素,-t参数用于去除每行末尾的换行符;< <(...)通过进程替换将yq的输出传递给readarray。
方案2:null分隔符安全读取(适配含特殊字符的键)
若键名包含空格、换行或其他特殊字符,使用null分隔符避免拆分错误:
yq e '.attr_keys.x | keys | .[] | tostring + "\x00"' config.yaml | while IFS= read -r -d '' parameter_key do echo "Key: $parameter_key" done
说明:tostring + "\x00"为每个键添加null字符作为分隔符;read -r -d ''会读取到null字符为止,确保完整读取每个键。
方案3:临时修改IFS拆分字符串
若需保留$(...)赋值方式,可临时修改IFS(内部字段分隔符)为换行符,强制按行拆分:
IFS=$'\n' read -r -d '' -a parameters_keys < <(yq e ".attr_keys.x | keys | .[]" config.yaml) for parameter_key in "${parameters_keys[@]}" do echo "Key: $parameter_key" done
说明:IFS=$'\n'指定按换行符拆分输入;-a参数将结果存入数组;-d ''确保读取到yq输出的结尾。
内容的提问来源于stack exchange,提问作者nglx
相关产品推荐
相关产品推荐

