RHEL下Bash4.1关联数组使用变量作为key取值为空如何解决
问题原因
该问题90%以上的概率是变量中包含肉眼不可见的特殊字符:最常见的是Windows格式文本带来的回车符\r、字段首尾多余的空白符,导致变量值和关联数组中存储的key表面看起来完全一致,实际内容不匹配。
另外你提供的代码中存在内层循环多余fi的语法错误,也需要同步清理。
修复方案
1. 修正关联数组导入逻辑,清理key的特殊字符
导入ip_lookup.txt时统一清除key中的回车符、首尾空白,保证存入的key是干净的IP地址:
declare -A ary # 先清理文件的Windows换行符,再逐行读取 while IFS== read -r key value; do # 移除回车符 key=${key//$'\r'/} # 移除首尾空白 key=${key##*[[:space:]]} key=${key%%[[:space:]]*} ary["$key"]="$value" done < <(sed 's/\r$//' "ip_lookup.txt")
2. 修正内层遍历逻辑,清理IP字段特殊字符
避免内外层变量重名,读取ip_list.txt时直接拆分字段,同时清理IP的特殊字符:
# 外层循环读service.txt,变量改名避免冲突 while IFS=$'\t' read -r svc_id svc_name do echo -e "${svc_id}\t${svc_name}" cat "access.log" | tr -d \" | sed "s/?wsdl.$PARTITION_COLUMN.\t/\t/g" | sed '/^[[:space:]]*$/d' | sed "s/?WSDL.$PARTITION_COLUMN.\t/\t/g" | grep "$svc_name" | awk '{ seen[$3] += 1 } END { for (i in seen) print seen[i],i }' | sort -nr | sed 's/ /\t/g' | head -n 2 > "ip_list.txt" # 内层循环直接读两个字段,去掉多余的fi while IFS=$'\t' read -r visit_cnt ip do # 清理IP字段的特殊字符 ip=${ip//$'\r'/} ip=${ip##*[[:space:]]} ip=${ip%%[[:space:]]*} echo -e "> $ip \t\t $visit_cnt \t\t ${ary[$ip]}" done < <(sed 's/\r$//' "ip_list.txt") done < <(sed 's/\r$//' "service.txt")
注:原代码中awk的seen[$3] += $1逻辑有误,你access.log的第一个字段是服务名,统计访问次数应该是seen[$3] += 1,已同步修正
3. 调试验证(可选)
如果修改后还是无法正常取值,可以执行以下命令打印变量的原始字节,确认是否存在隐藏字符:
ip=${line[1]} echo "变量值字节内容:" echo "$ip" | od -c echo "关联数组所有key:" for k in "${!ary[@]}"; do echo "$k" | od -c; done
内容的提问来源于stack exchange,提问作者qmail_madrid
相关产品推荐
相关产品推荐

