Bash中关联数组按整数列排序异常的解决咨询
解决关联数组排序时
sort按数字首字符排序的问题 嘿,我完全懂你遇到的糟心事——明明想按第一列的整数值从大到小排序,结果sort却把数字当字符串处理,只盯着首字符比大小,导致1,325居然排在505后面,这确实够闹心的。
问题根源
sort默认是按**字典序(字符串顺序)**做比较的,而你的第一列数字带了千分位分隔符(,),它会把1,325当成一串普通字符,和505对比时,首字符1的ASCII值比5小,自然就被排到后面去了,完全没按实际数值大小来判断。
两种可行的解决方案
方案1:让sort识别带千分位的数值(最简单)
我们可以通过指定LC_NUMERIC环境变量,告诉sort当前数字的千分位分隔符是逗号,这样-n(数值排序)参数就能正确解析这些数字了:
for i in "${!hash[@]}"; do printf "%'d %s\n" "${hash[$i]}" "$i"; done | LC_NUMERIC=en_US.UTF-8 sort -rn -k1
原理:en_US.UTF-8这个区域设置(locale)的数值格式里,千分位用逗号分隔,sort会遵循这个规则把1,325解析成整数1325,然后按实际数值大小排序。如果你的系统没有这个locale,可以用locale -a命令查看可用选项,找一个千分位用逗号的locale就行(比如en_GB.UTF-8也适用)。
方案2:先去掉逗号排序,再恢复千分位格式
如果不想依赖locale,也可以先把数字里的逗号去掉,让sort按纯整数排序,之后再把千分位逗号加回去:
for i in "${!hash[@]}"; do printf "%'d %s\n" "${hash[$i]}" "$i"; done | sed 's/,//g' | sort -rn -k1 | awk '{printf "%'\''d %s\n", $1, substr($0, index($0,$2))}'
步骤拆解:
sed 's/,//g':把所有行里的逗号去掉,比如1,325变成1325;sort -rn -k1:按纯整数倒序排序;awk:把排序后的第一列重新格式化成带千分位的数字,同时完整保留后面的字符串内容。
验证效果
用你的示例数据测试,两种方案都会得到符合预期的排序结果:
1,325 mail 505 root 17 adm 2 games 1 bin
内容的提问来源于stack exchange,提问作者user3066571
相关产品推荐
相关产品推荐

