如何让 ls 首先对下划线字符进行排序?

如何让 ls 首先对下划线字符进行排序?

如果我想将文件和目录与同一级别的其他文件和目录分开,我喜欢能够使用下划线前缀来命名文件和目录。例如,在 Windows 和 Mac 上,在文件前添加下划线前缀会将其排序到顶部,位于以字母数字字符开头的文件前面。

我的谷歌搜索发现它与 LC_COLLATE 和我当前的语言环境(en_US)有关。没关系,尽管我真的不明白为什么 en_US 没有按预期排序。

基于ICU Collat​​e演示现场将 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 扩展。

您可以使用文件名模式来运行lsshell 已排序的文件列表,从而绕过所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

相关内容