如何利用for in循环筛选roles.txt中不在SQL结果内的角色
解决方法:找出roles.txt中不在SQL查询结果里的角色
嘿,我看了你的脚本,现在帮你调整一下,实现你要的功能。先说说原脚本里的几个小问题:
- 你的
for filename in roles.txt写法不对,这样只会把文件名roles.txt当成循环变量,而不是读取文件里的每一行角色。 - 循环里的
if语句没有闭合fi,脚本会直接报错。 - 当检测到SQL结果为空时,你需要输出对应的角色,而不是固定的提示文本。
基础修正版脚本
先给你一个最直接的修正版本,逐行读取角色并查询SQL,输出不存在的角色:
#!/bin/bash # 遍历roles.txt里的每一行角色 while read -r role; do # 跳过文件中的空行(如果有的话) [[ -z "$role" ]] && continue # 执行SQL查询,-N用于去掉结果的列名 sql_output=$(mysql -N -e "SELECT ROLE_NAME FROM SENTRY_ROLE WHERE ROLE_NAME = '$role';") # 如果查询结果为空,说明该角色不在数据库中,输出它 if [ -z "$sql_output" ]; then echo "$role" fi done < roles.txt
高效优化版脚本
如果你的roles.txt里角色数量很多,上面的方法每一行都跑一次SQL会比较低效。咱们可以先一次性把数据库里的所有角色查出来存到数组里,再遍历roles.txt做本地检查,这样只需要执行一次SQL:
#!/bin/bash # 一次性查询所有已存在的角色,存入数组 mapfile -t existing_roles < <(mysql -N -e "SELECT ROLE_NAME FROM SENTRY_ROLE;") # 遍历roles.txt的每一行角色 while read -r role; do [[ -z "$role" ]] && continue # 检查当前角色是否在已存在的角色数组中 if ! [[ " ${existing_roles[*]} " =~ " $role " ]]; then echo "$role" fi done < roles.txt
补充说明
read -r是为了正确处理包含反斜杠的行(虽然你的角色名大概率不会有,但养成好习惯更稳妥)。mapfile -t会把SQL输出的每一行存到数组existing_roles里,-t参数会自动去掉每行末尾的换行符。- 数组检查时用
" ${existing_roles[*]} " =~ " $role "是为了避免部分匹配的问题(比如不会把admin1误判成admin)。
内容的提问来源于stack exchange,提问作者TheNewGuy
相关产品推荐
相关产品推荐

