Ls

如何讓“ls”首先顯示點文件,同時保持不區分大小寫?

  • April 5, 2021

在目錄中創建以下文件。

$ touch .a .b a b A B 你好嗎

我的預設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 你好嗎

可以 更改 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 你好嗎

不幸的是,這使得排序順序區分大小寫,即AandB之前aand b。有沒有辦法先列印點文件,同時保持不區分大小寫(A並且在anda之前)?B``b

編輯:嘗試修改 LC_COLLATE

到目前為止,沒有一個答案完全複製了 easy 的功能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

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

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

我刪除了這一行,執行sudo locale-gen,然後重新啟動了我的電腦。不幸的是,這並沒有改變什麼。

OP 與編輯非常接近/usr/share/i18n/locales/iso14651_t1_common,但訣竅是不要刪除該行

<U002E> IGNORE;IGNORE;IGNORE;<U002E> # 47 .

而是將其修改為

<U002E> <RES-1>;IGNORE;IGNORE;<U002E> # 47 .

為什麼這有效

這些IGNORE語句指定<U002E>按字母順序排列單詞時將忽略句點(也稱為句點或字元)。要使您的點文件排在第一位,請更改IGNORE為所有其他字元之前的整理符號。整理符號由以下行定義

collating-symbol <something-inside-angle-brackets>

並且它們按線條的外觀排序

<something-inside-angle-brackets>

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

有關使用 LC_COLLATE 進行字元排序的詳細資訊

<U002E>有三個IGNORE陳述,因為在平局的情況下可以多次比較字母。要理解這一點,請考慮小寫a和大寫A(它們是實際比較四次的一組字元的一部分):

<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A

多輪比較允許以“a”和“A”開頭的文件組合在一起,因為<a>在第一次比較期間兩者都進行比較,下一個字母確定排序。如果以下所有字母都相同(例如a.txtA.txt),則第三遍將a.txt放在第一位,因為小寫字母的整理符號<MIN>出現在第 3467 行,在大寫字母的整理符號之前<CAP>(第 3488 行)。

實施此更改

如果您希望每次程序使用 訂購信件時句點都排在第一位LC_COLLATE,您可以iso14651_t1_common如上所述進行修改並重建您的位置文件。但是,如果您只想在沒有 root 訪問權限的情況下進行此更改,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

要替換預設ls排序,請創建一個名為 的 BASH 腳本ls

#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"

將其保存在路徑上之前出現的某個/usr/bin位置,並使用chmod +x ls.

引用自:https://unix.stackexchange.com/questions/288333