Bash sort -d命令未按预期处理点字符的排序问题咨询
问题原因分析
你遇到的问题核心在于sort -d选项的行为和系统locale的排序规则:
-d(字典序模式)的作用:这个选项会让sort在排序时只考虑字母、数字和空格,其他所有字符(比如你的.)都会被忽略,用于初步的排序比较。- 字符串相等后的二次比较:当两个字符串在忽略非字母数字字符后完全相同时(比如你的
toto.dlabla和totodlabla,忽略.后都是toto dlabla的有效字符序列),sort会转而比较完整的原始字符串。 - locale的排序规则影响:在大多数现代系统默认的locale(比如
en_US.UTF-8)中,字母的排序优先级高于标点符号。也就是说,字母d的排序位置比.更靠前。所以在完整字符串比较时,totodlabla的第五个字符是d,比toto.dlabla的第五个字符.更小,因此前者被排在了前面,导致结果不符合你的预期。
解决方案
根据你的需求,有两种常用的解决方式:
1. 去掉-d选项,使用默认排序
默认的sort命令会考虑所有字符,基于当前locale的规则进行排序(在ASCII顺序下,.的编码比d小,会排在前面):
IFS=$'\n'; echo "${a[*]}" | sort; unset IFS
执行后会得到你预期的结果:
toto.blabla toto.dlabla totodlabla
2. 强制使用ASCII顺序排序(不受locale影响)
如果你需要严格按照ASCII字符编码值排序,不管系统locale的设置,可以临时设置LC_COLLATE=C:
IFS=$'\n'; echo "${a[*]}" | LC_COLLATE=C sort; unset IFS
这种方式下,所有字符都会按照它们的ASCII编码值比较,.(ASCII 46)小于d(ASCII 100),因此也会得到正确的排序结果。
内容的提问来源于stack exchange,提问作者Olivier
相关产品推荐
相关产品推荐

