如何在保持不区分大小写的同时让“ls”首先显示点文件?

Spa*_*awk 27 ls locale

在目录中创建以下文件。

$ touch .a .b a b A B ???
Run Code Online (Sandbox Code Playgroud)

我的默认ls顺序忽略了前导点的存在,将它们与其他文件混合在一起。

$ ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 ???
Run Code Online (Sandbox Code Playgroud)

可以 更改 LC_COLLATE为先放置点文件。

$ LC_COLLATE=C ls -Al
total 0
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 .b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 A
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 B
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 a
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:03 b
-rw-r--r-- 1 sparhawk sparhawk 0 Jun  8 17:06 ???
Run Code Online (Sandbox Code Playgroud)

不幸的是,这使得排序顺序区分大小写,即AandBaand之前b。有没有办法先打印点文件,同时保持不区分大小写(AaB和之前b)?

编辑:试图修改 LC_COLLATE

到目前为止,没有一个答案可以完全复制ls轻松的功能。可以想象,我可以将其中的一些包装在一个函数中,但这必须包含一些关于(例如)如何在没有参数的情况下工作与提供目录作为参数的详细代码。或者如何处理显式-d标志。

或者,我认为也许可以LC_COLLATE使用更好的方法。但是,我似乎无法做到这一点。我目前正在使用LC_COLLATE="en_AU.UTF-8". 我检查过/usr/share/i18n/locales/en_AU(虽然我不确定这是否是正确的文件,因为我看不到任何对 的引用UTF-8);我发现了以下内容。

LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE
Run Code Online (Sandbox Code Playgroud)

/usr/share/i18n/locales/iso14651_t1包含copy "iso14651_t1_common". 最后,/usr/share/i18n/locales/iso14651_t1_common包含

 <U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .
Run Code Online (Sandbox Code Playgroud)

我删除了这一行,运行sudo locale-gen,然后重新启动了我的电脑。不幸的是,这没有任何改变。

bea*_*dip 17

OP与编辑非常接近/usr/share/i18n/locales/iso14651_t1_common,但诀窍是不要删除该行

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .
Run Code Online (Sandbox Code Playgroud)

而是将其修改为

<U002E> <RES-1>;IGNORE;IGNORE;<U002E> # 47 .
Run Code Online (Sandbox Code Playgroud)

为什么这有效

这些IGNORE语句指定在<U002E>按字母顺序排列单词时将忽略句号(又名句点或字符)。要使您的点文件排在第一位,请更改IGNORE为排在所有其他字符之前的整理符号。整理符号由类似的行定义

collating-symbol <something-inside-angle-brackets>
Run Code Online (Sandbox Code Playgroud)

它们是按线的外观排序的

<something-inside-angle-brackets>
Run Code Online (Sandbox Code Playgroud)

在我的 副本中iso14651_t1_common,第一个排序符号是<RES-1>,它出现在第 3458 行。如果您的文件不同,请使用最先排序的排序符号。

有关使用 LC_COLLATE 进行字符排序的详细信息

<U002E>有 3 个IGNORE语句,因为如果出现关系,可以多次比较字母。要理解这一点,请考虑小写a和大写A(它们是实际比较四次的一组字符的一部分):

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
Run Code Online (Sandbox Code Playgroud)

多轮比较允许将以“a”和“A”开头的文件组合在一起,因为<a>在第一遍期间比较两者,下一个字母确定排序。如果以下所有字母都相同(例如a.txtA.txt),则第三遍将放在a.txt最前面,因为小写字母的整理符号<MIN>出现在第 3467 行,在大写字母的整理符号<CAP>(第 3488 行)之前。

实施此更改

如果您希望每次程序使用 订购信件都首先出现句点LC_COLLATE,您可以iso14651_t1_common按上述方式进行修改并重建您的位置文件。但是,如果你想使这一变化ls和无根的访问,可以将原有的语言文件修改之前复制到另一个目录。

我做了什么

我的默认语言环境是en_US,所以我复制en_USiso14651_t1以及iso14651_t1_common$HOME/path/to/new/locales。在那里我进行了上述更改并重iso14651_t1_common命名en_USen_DOTFILE. 接下来我编译了 en_DOTFILE 语言环境

localedef -i en_DOTFILE -f UTF-8 -vc $HOME/path/to/new/locales/en_DOTFILE.UTF-8
Run Code Online (Sandbox Code Playgroud)

要替换默认ls排序,请创建一个名为 的 BASH 脚本ls

#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"
Run Code Online (Sandbox Code Playgroud)

将其保存/usr/bin在路径上出现之前的某个位置,并使用chmod +x ls.


Ste*_*itt 11

您可以改用 shell 的排序顺序(这可能不涉及语言环境的排序顺序;bash, AT&T ksh, yashtcshzsh给出预期的结果,mkshdash不是。fish似乎给出了不区分大小写的顺序,但当存在非 ASCII 时给出不同的结果人物):

ls -dUl -- .* *
Run Code Online (Sandbox Code Playgroud)

这给出ls了要列出的文件(和目录)的明确列表,并停用ls的排序(-U,这是一个 GNU 扩展)。

有一些注意事项,具体取决于您使用的外壳。

  • 使用zshnomatch如果目录不包含隐藏和非隐藏文件,默认选项将导致命令失败;您可以禁用nomatch以避免这种情况,但最好改为这样做set -o cshnullglob(并且只有在没有任何 globs 匹配(t)csh或早期的 Unix shell 时,命令才会失败)。
  • With zsh,pdksh及其派生 and fish,.*的扩展不包括.and ..,所以这匹配ls -Al。与其他壳...包括这样它匹配ls -al。在后一种情况下,您需要更改通配模式以排除...( ls -dUl -- ..?* .[!.]* *)。
  • 除了 in fish, (t)cshor zsh,如果任何通配模式不匹配任何内容,ls将产生错误消息;您可以通过设置nullglob选项(bashzsh至少)或重定向stderr/dev/null( ls -dUl -- ..?* .[!.]* * 2>/dev/null)来避免这种情况。如果您使用nullglob,请注意可能导致的令人惊讶的行为(请参阅Shell 吃 `?` 字符)。fish行为与bashwithnomatch除了交互时,将为每个没有匹配的 glob 发出警告消息。

(感谢Stéphane Chazelas的所有反馈!)