给定目录中的几个文件,data
以下 ls 命令会根据它们的排序提供令人惊讶的结果:
for f in data/*; do echo $f; done
data/CitiesBaselineCounts2015010520150112.49.csv
data/CitiesBaselineCounts2015010520150112.4.csv
data/CitiesBaselineCounts2015010520150112.50.csv
data/CitiesBaselineCounts2015010520150112.5.csv
data/CitiesBaselineCounts2015010520150112.6.csv
data/CitiesBaselineCounts2015010520150112.7.csv
data/CitiesBaselineCounts2015010520150112.8.csv
data/CitiesBaselineCounts2015010520150112.9.csv
data/CitiesBaselineCounts2015010520150112.csv
该.
字符是 ascii 46-,它位于所有数字 (48 至 57) 的代码之前。
那么顺序就是不是词典学。什么是该命令使用的排序规则ls
是什么?
答案1
当您执行for f in data/*
此操作时,文件名的枚举是由您的 shell 而不是“ls”完成的。通常,shell 将按字典顺序排序(bash 就是如此),但它们可能会使用您的 LC_COLLATE 语言环境排序顺序。也许您的特定 shell 根本不排序。
目录条目通常不排序,但这取决于底层文件系统。用于ls -f
列出不排序的目录。
当您说 时ls *
,首先 shell 会扩展 * 并可能对结果进行排序,然后 ls 将再次对文件名进行排序。
答案2
ls、sort 和你的脚本都给出了相同的顺序,即根据每个位置的 ASCII 值按字典顺序排列,但非字母数字会被忽略
abc.
abc..
abc0
abc1
abc_1
abc.1
abc..1
abc.1.4
abc.1..4
abc.1.5
abc2
abc~2
abc_2
abc-2
abc.2
abc#2
abc%2
abc3
abc4
abc4.1
abc4.2
abc49
abc_9
abca
abcA
abcc
请参阅问题 631402 的答案,了解更多讨论,包括关闭区域设置,这样您就可以按 ASCII 值(包括符号)进行字典排序