Shell脚本按分隔符提取字符串取值异常的解决方法
问题根因
cut 拆分失败始终返回完整字符串,本质是命令没有匹配到指定的-分隔符,常见诱因有三个:
- 数据库返回的结果中,肉眼可见的横杠不是ASCII半角减号(编码
0x2d),而是全角减号、长短破折号等Unicode字符,视觉上和普通减号无差异但编码不同 - SQL查询结果带Windows格式的
\r回车符、其他不可见控制字符,干扰分隔符匹配 - 原写法中
echo $STRING未给变量加双引号,若字符串包含空格、特殊字符会被Shell意外展开,导致cut接收到的内容异常
修复步骤
第一步:先排查确认实际字符
先执行命令打印字符串的原始编码,定位分隔符异常问题:
# 打印字符的可视化原始格式 echo "$STRING" | od -c
如果输出中看到分隔符位置不是标准-,或者行尾有\r标记,先做预处理:
# 清除所有回车符、替换所有类横杠字符为标准半角减号 STRING=$(echo "$STRING" | tr -d '\r' | tr '\xe2\x80\x93\xe2\x80\x94\xef\xbc\x8d' '-')
第二步:选择稳定的拆分方式
方式1:Shell内置语法拆分(无外部命令依赖,性能最优)
不需要多次调用cut,直接用Shell原生字符串截取能力即可,适合追求脚本执行效率的场景:
A=${STRING%%-*} tmp=${STRING#*-} B=${tmp%%-*} C=${tmp#*-}
方式2:awk一次拆分(容错性最高)
一次调用awk完成三个字段提取,自动忽略首尾空白、控制字符干扰,写法简洁:
read -r A B C < <(echo "$STRING" | awk -F'-' '{gsub(/\r/,""); print $1,$2,$3}')
方式3:数组拆分(适合多字段场景)
如果后续拆分字段数量会增加,用数组存储拆分结果扩展性更好:
IFS='-' read -r -a str_arr <<< "$STRING" A=${str_arr[0]} B=${str_arr[1]} C=${str_arr[2]}
原写法的额外注意点
原代码中echo $STRING没有给变量加双引号,当字符串包含空格、*等通配符时会被Shell展开,导致命令接收到的内容不符合预期,所有Shell变量引用建议都加上双引号,即写成echo "$STRING"。
内容的提问来源于stack exchange,提问作者Snehal Vadlakonda
相关产品推荐
相关产品推荐

