如果我想将文件和目录与同一级别的其他文件和目录分开,我喜欢能够使用下划线前缀来命名文件和目录。例如,在 Windows 和 Mac 上,在文件前添加下划线前缀会将其排序到顶部,位于以字母数字字符开头的文件前面。
我的谷歌搜索发现它与 LC_COLLATE 和我当前的语言环境(en_US)有关。没关系,尽管我真的不明白为什么 en_US 没有按预期排序。
基于ICU Collate演示现场将 locale 设置为 en_US_POSIX 当然似乎具有我正在寻找的排序顺序(您必须编辑示例数据并添加一些下划线来测试它)。但我真的不知道如何在我的 Linux shell 中应用它。
理想情况下,我希望能够在 bash 配置中进行一些设置,以便 ls 始终首先对下划线进行排序。我该怎么做呢?
答案1
如果您不想混合使用小写和大写,请将您的区域设置设置为C
,这将按数字顺序接受字符。_
介于大写和小写之间。
$ LC_COLLATE=C ls
BAR FOO _score _under hello world
$ LC_COLLATE=en_US ls
BAR FOO hello _score _under world
区域设置LC_MESSAGES
(错误消息的语言)、LC_CTYPE
(字符集)和LC_TIME
(日期和时间格式)非常有用。LC_COLLATE
而且LC_NUMERIC
通常比它们的价值更麻烦,我不建议设置它们。正确的字典排序比LC_COLLATE
预期指定的更复杂,并且当您在正则表达式中使用字符范围时,它可能会导致各种奇怪的行为。LC_NUMERIC
主要是装饰性的,除非出现严重错误,因为某些程序生成的数字带有除 之外的小数分隔符.
。
答案2
如果您无法ls
按照您想要的方式排序,请尝试 shell 扩展。
您可以使用文件名模式来运行ls
shell 已排序的文件列表,从而绕过所ls
使用的方法。
ls -lf _* [!_]*
假设你有文件
_a a _b b _c c
这就像跑步
ls -lf _a _b _c a b c
解释:
_*
是一个 shell 模式,匹配任何以下划线开头的文件名,按字母顺序展开。
[!_]*
匹配任何文件名不是以下划线开头,按字母顺序展开。
-f
告诉ls
不是排序,因为 shell 已经这样做了。
更多信息:bash 文件名扩展
如果当前目录中有目录,您将需要运行如下命令以避免 ls 列出目录中的文件:
ls -lfd _* [!_]*
答案3
不幸的是,Linux 使用 glibc 来获取语言环境信息,而不是 ICU,因此如果不花费大量精力将 ICU 改造为 glibc 或补充 glibc 中的语言环境信息,就无法直接将其应用到 Linux。
答案4
添加-f
开关(没有排序)使它对我来说是这样的。
man ls
[root@dusknoir ~/java/test]# ls -fl
total 0
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 _1
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 _2
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 _3
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 1
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 2
-rw-r--r-- 1 root wheel 0 Jun 1 13:27 3