如何通过if语句判断输入字符串是否在变量的逗号分隔列表中?
如何精确匹配逗号分隔列表中的元素?
看起来你之前的代码要么是完全匹配整个字符串(第一个版本),要么搞反了匹配方向导致精确匹配失效(第二个版本)。咱们一步步来解决这个问题:
问题分析
你第二个版本的核心错误是匹配方向搞反了:你写的[ ",${var}," = *",${groups},"* ],是在判断「输入值加前后逗号」是否包含「整个列表加前后逗号」,这和你要的「输入值是否在列表里」完全相反。另外,[ ]语法对通配符支持有限,建议用bash的[[ ]]来做模式匹配。
修正方案1:逗号边界匹配(最贴近你的原有代码)
只需要调整匹配方向,并用[[ ]]处理即可:
groups="$(aws iam list-groups --output text | awk '{print tolower($5)}' | sed '$!s/$/,/' | tr -d '\n')" echo "please enter data" read var # 关键:检查列表的逗号包裹字符串是否包含输入值的逗号包裹字符串 if [[ ",${groups}," == *",${var},"* ]]; then echo "$var is in the list" else echo "$var is not in the list" fi
原理是给列表和输入值都加上前后逗号,比如列表变成,one,two,three,,输入值变成,two,,这样就能避免部分匹配(比如输入tw不会被误判为匹配two),保证只有完全一致的元素才会被匹配到。
修正方案2:转成数组遍历(更直观可靠)
把逗号分隔的字符串转成bash数组,逐个元素精确匹配,这种方法可读性更强,也能处理带空格的组名:
# 先获取组名列表(每行一个) groups_list="$(aws iam list-groups --output text | awk '{print tolower($5)}')" # 转成逗号分隔字符串(保留原有变量格式) groups=$(echo "$groups_list" | sed '$!s/$/,/' | tr -d '\n') echo "please enter data" read var # 统一转小写,和aws输出格式对齐 var_lower=$(echo "$var" | tr '[:upper:]' '[:lower:]') # 把逗号分隔字符串转成数组 IFS=',' read -r -a groups_array <<< "$groups" found=0 for item in "${groups_array[@]}"; do if [[ "$item" == "$var_lower" ]]; then found=1 break fi done if [[ $found -eq 1 ]]; then echo "$var is in the list" else echo "$var is not in the list" fi
修正方案3:用grep精确匹配(最简洁)
其实你完全不需要把输出拼成逗号分隔字符串,直接用每行一个组名的原始输出,配合grep的精确匹配参数更简单:
echo "please enter data" read var var_lower=$(echo "$var" | tr '[:upper:]' '[:lower:]') # 直接检查输入值是否存在于组名列表中(整行精确匹配) if aws iam list-groups --output text | awk '{print tolower($5)}' | grep -Fxq "$var_lower"; then echo "$var is in the list" else echo "$var is not in the list" fi
这里的grep参数说明:
-F:把输入模式当作固定字符串,避免正则特殊字符干扰-x:要求整行完全匹配,杜绝部分匹配-q:静默模式,只返回状态不输出内容
总结
- 如果已有现成的逗号分隔字符串,用方案1最快捷
- 如果需要对组名做后续操作,方案2的数组更灵活
- 追求代码简洁的话,方案3是最优选择
内容的提问来源于stack exchange,提问作者hhh0505
相关产品推荐
相关产品推荐

