如何使用jq从JSON字符串填充Bash脚本的USERS与ACTIONS变量?
解决方案
要完成脚本中USERS和ACTIONS变量的填充并完善循环逻辑,你可以利用jq的JSON解析能力结合Bash数组来实现,具体操作如下:
1. 填充USERS数组
通过jq提取JSON对象的所有键(即用户名),并将结果读入Bash数组,确保能正确处理包含特殊字符的用户名:
mapfile -t USERS < <(jq -r 'keys[]' <<< "$USER_ACTIONS")
jq -r 'keys[]':以原始字符串格式输出JSON对象的所有键,每个键单独占一行mapfile -t USERS:将标准输入的每一行内容存入USERS数组,-t参数用于去除每行末尾的换行符
2. 填充ACTIONS数组
在用户循环中,针对当前用户名,用jq提取对应的动作列表,同样读入Bash数组:
mapfile -t ACTIONS < <(jq -r --arg user "$user" '.[$user][]' <<< "$USER_ACTIONS")
--arg user "$user":将Bash变量user的值传递给jq作为内部变量$user.[$user][]:访问JSON对象中对应用户名的数组,并逐个输出数组元素
3. 修正循环逻辑
循环时需要遍历数组的所有元素,因此要使用数组展开语法"${USERS[@]}"和"${ACTIONS[@]}",避免空格等特殊字符导致的拆分错误。另外,原脚本中的${command}未定义,需替换为实际要执行的CLI命令。
完整修改后的脚本
#!/usr/bin/env bash jq --version > /dev/null 2>&1 || { echo >&2 "jq is required but it's not installed. Aborting."; exit 1; } read -r -d '' USER_ACTIONS << EOM { "user1": [ "action1" ], "user2": [ "action2", "action3" ] } EOM # 填充USERS数组:提取所有用户名 mapfile -t USERS < <(jq -r 'keys[]' <<< "$USER_ACTIONS") for user in "${USERS[@]}"; do # 填充ACTIONS数组:提取当前用户对应的所有动作 mapfile -t ACTIONS < <(jq -r --arg user "$user" '.[$user][]' <<< "$USER_ACTIONS") for action in "${ACTIONS[@]}"; do # 替换为实际要执行的CLI命令,此处用echo做示例 echo "Executing my-cli-command ${user}-${action}" done done
兼容旧版Bash的替代方案
如果你的环境不支持mapfile(比如Bash版本低于4.0),可以用read -a替代:
# 填充USERS IFS=$'\n' read -r -a USERS <<< "$(jq -r 'keys[]' <<< "$USER_ACTIONS")" # 填充ACTIONS IFS=$'\n' read -r -a ACTIONS <<< "$(jq -r --arg user "$user" '.[$user][]' <<< "$USER_ACTIONS")"
IFS=$'\n'设置内部字段分隔符为换行符,确保每个用户名/动作作为数组的一个独立元素,不会被空格拆分
内容的提问来源于stack exchange,提问作者Petra Barus
相关产品推荐
相关产品推荐

