次のファイルをディレクトリに作成します。
$ 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 你好嗎
I canchangeLC_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 你好嗎
残念ながら、これはソート順の大文字と小文字を区別します。つまり、A
とB
はa
とb
の前に置かれます。大文字と小文字を区別せずにドットファイルを最初に印刷する方法はありますか(A
とa
はB
とb
に先行します)?
これまでのところ、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
の編集に非常に近かったが、トリックはdelete行ではない
<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に表示されます。ファイルが異なる場合は、最初に並べられた照合記号を使用します。
<U002E>
には3つのIGNORE
ステートメントがあります。同順位の場合、文字を複数回比較できるためです。これを理解するために、小文字のa
と大文字のA
を検討してください(これらは実際に4回比較される文字のグループの一部です)。
<U0061> <a>;<BAS>;<MIN>;IGNORE # 198 a
<U0041> <a>;<BAS>;<CAP>;IGNORE # 517 A
複数回の比較を行うと、「a」と「A」で始まるファイルをグループ化できます。これは、最初のパスで両方が<a>
として比較され、次の文字が順序を決定するためです。次のすべての文字が同じである場合(例:a.txt
とA.txt
)、小文字a.txt
の照合記号が行に表示されるため、3番目のパスでは<MIN>
が最初に配置されます。 3467、大文字の照合記号の前<CAP>
(3488行目)。
期間を最初にしたい場合毎回プログラムはLC_COLLATE
を使用して手紙を注文します。上記のようにiso14651_t1_common
を変更して、場所ファイルを再構築できます。しかし、この変更をしたい場合onlyをls
に変更し、rootアクセスなしで、元のロケールファイルを変更する前に別のディレクトリにコピーできます。
デフォルトのロケールはen_USなので、en_US
、iso14651_t1
、およびiso14651_t1_common
を$HOME/path/to/new/locales
にコピーしました。そこで、上記の変更をiso14651_t1_common
に加え、en_US
をen_DOTFILE
に名前変更しました。次にen_DOTFILEロケールをコンパイルして
localedef -i en_DOTFILE -f UTF-8 -vc $HOME/path/to/new/locales/en_DOTFILE.UTF-8
デフォルトのls
の順序を置き換えるには、ls
というBASHスクリプトを作成します。
#!/bin/bash
LOCPATH=$HOME/path/to/new/locales LANG=en_DOTFILE.UTF-8 ls "$@"
パスの/usr/bin
の前のどこかに保存し、chmod +x ls
で実行可能にします。
代わりにシェルの並べ替え順序を使用できます(ロケールの照合順序は含まれない場合があります。bash
、AT&T ksh
、yash
、tcsh
、zsh
は期待される結果を提供しますが、mksh
およびdash
は提供しません。fish
は大文字と小文字を区別しない順序を示しますが、ASCII以外の文字がある場合は結果が異なります) :
ls -dUl -- .* *
これにより、リストするファイル(およびディレクトリ)の明示的なリストがls
に与えられ、ls
のソート(-U
、GNU拡張子)が非アクティブになります)。
使用しているシェルによっては、いくつかの注意点があります。
zsh
では、デフォルトのnomatch
オプションを使用すると、ディレクトリに隠しファイルと非隠しファイルの両方が含まれていない場合、コマンドが失敗します。それを避けるためにnomatch
を無効にすることもできますが、代わりにset -o cshnullglob
を実行することをお勧めします(そして(t)csh
または初期のUnixシェルのように、どのglobも一致しない場合にのみ失敗するコマンド) 。zsh
、pdksh
とその派生物、およびfish
を使用すると、.*
の展開には.
と..
が含まれないため、これは一致します。 ls -Al
。他のシェルでは、.
および..
が含まれているため、ls -al
と一致します。後者の場合、.
および..
(ls -dUl -- ..?* .[!.]* *
)を除外するようにグロビングパターンを変更する必要があります。fish
、(t)csh
、またはzsh
を除いて、いずれかのグロビングパターンが何にも一致しない場合、ls
はエラーメッセージを生成します。これを回避するには、nullglob
オプションを設定するか(少なくともbash
またはzsh
で)、またはstderr
を/dev/null
にリダイレクトします( ls -dUl -- ..?* .[!.]* * 2>/dev/null
)。 nullglob
を使用する場合、原因となる可能性のある驚くべき動作に注意してください(「 シェルが「?」文字を食べる を参照)。 fish
はbash
とnomatch
のように動作しますが、対話型の場合、一致しない各グロブに対して警告メッセージが発行されます。(すべてのフィードバックに対して StéphaneChazelas に感謝します!)
あなたは単に2つの別々のls
コマンドを使うかもしれません:
$ ls -dl ..?* .[^.]* 2>/dev/null ; ls -dl *
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 .a
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 .b
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 a
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 A
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 b
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 B
-rw-r--r--. 1 sparhawk sparhawk 0 8 Jun 09:29 你好嗎
これまでの他の回答とは異なり、このアプローチでは、最初に.
エントリと..
エントリを避けてドットファイルを表示し、次に残りのエントリをls
のアルファベット順に表示します。
@StephenKittの回答は、同じ結果を達成するために改善される可能性があります。
$ ls -dUl ..?* .[^.]* * 2>/dev/null