lsで最初にアンダースコア文字をソートするにはどうすればよいですか?


20

同じレベルの他のファイルやディレクトリとは別にしたい場合は、アンダースコアのプレフィックスを付けてファイルやディレクトリに名前を付けることができるのが好きです。たとえば、WindowsおよびMacの場合、ファイルの先頭にアンダースコアを付けると、英数字で始まるファイルの前に、ファイルが先頭にソートされます。

私のグーグルは、LC_COLLATEと私の現在のロケール(en_US)に関係していることが判明しました。それは問題ありませんが、en_USが期待どおりにソートされない理由は本当にわかりません。

ICU Collat​​eデモサイトに基づいて、ロケールをen_US_POSIXに設定すると、確かに私が探している並べ替え順序を持っているように見えます(テストするには、サンプルデータを編集し、アンダースコアを追加する必要があります)。しかし、Linuxシェルでこれをどのように適用するかはあまりわかりません。

理想的には、lsが常にアンダースコアを最初にソートするように、bash構成で何かを設定できるようにしたいと思います。これをどうやってやるの?


ICU Collat​​eをデフォルトで使用したり、「ロケールのフェッチルール」経由でen_US_POSIX.txtを使用して複製することはできません。使用した設定を説明できますか?
ミケル


上記で提供したリンクを使用して@Mikelを実行し、テストデータにアンダースコアを追加してから、送信して並べ替えの結果を確認します。
トム・オージェ

それはまさに私がやったことであり、アンダースコアで始まる文字列は、アンダースコアが存在しないかのように、先頭ではなく中央でソートされます。
ミケル

1
照合順序の定義を実際に変更することに関する問題は、unix.stackexchange.com / questions / 421908です。
JdeBP

回答:


5

ls希望する方法でソートできない場合は、シェル拡張を試してください。

ファイル名パターンを使用lsして、ls使用する方法をバイパスして、シェルが既にソートしたファイルのリストで実行できます。

ls -lf _* [!_]*

ファイルがあると仮定して

_a a _b b _c c

これは走るようなものです

ls -lf _a _b _c a b c

説明:

_* は、アンダースコアで始まるファイル名に一致するシェルパターンで、アルファベット順に展開されます。

[!_]*アンダースコアで始まらない任意のファイル名に一致し、アルファベット順に展開されます。

-fシェルはすでにソートしているため、ソートlsないように指示します。

詳細:bashファイル名の展開

現在のディレクトリにディレクトリがある場合、次のようなコマンドを実行して、ディレクトリ内のファイルを一覧表示しないようにします。

ls -lfd _* [!_]*

7
ちなみに、DOS / Windows / OSXは実際にアンダースコアを他の何かの前に配置しません。アンダースコアを文字の前に入れて大文字と小文字を区別せずにソートしますが、その他の句読文字はアンダースコアの前後に配置します。使用する_ファイルが最初に表示させるためには、OS固有のハックです。このハックのUNIXバージョンでは、ファイル名を大文字で開始します。デフォルトのUNIX規則では、ファイル名には小文字のみを使用します。
ジル 'SO-悪であるのをやめる

4
またはゼロ; 例えば00README
mattdm

1
@Gilles +1は、重要なファイルに大文字を使用してそれらを最初にlsにするUNIXのベストプラクティスです。結局のところ、それが慣習なら、おそらく他のOSのようにunixを強制的に動作させるのではなく、単にそれを採用するのが最善です。素晴らしいヒントをありがとう。
トム・オージェ

1
@TomAuger -fls独自のソートを行わないように指示するため、引数は渡された順に表示されます。各シェルのワイルドカード拡張の結果_*とは、[!_]*辞書順でソートされたリストです。
ジル 'SO-悪

1
@TomAugerへの引数ls_、シェルによって生成されるときに(2つのグループ:で始まるグループ、次に他のグループで)ソートされます。実行echo ls -lf _* [!_]*して何が起こるかを確認します。-fフラグが伝えるls任意の並べ替えをしません。
ジル 'SO-悪であるのをやめる

16

小文字と大文字を混在させたくない場合は、ロケールを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いくつかのプログラムが以外の小数点区切り記号付きの数値を生成したために何かがひどく間違った場合を除いて、ほとんどは化粧品です.


+1非常に興味深い。したがって、このフォームを使用して、lsのその1つのインスタンスだけに環境変数LC_COLLATEを一時的に設定していますか?そうですか?
トム・オージェ

1
アンダースコアを大文字の前に表示する方法はありますか?
トム・オージェ

1
@TomAugerはい、実行するシェルの値のみ(または値の不在)の環境でのみにVAR=value cmd設定VARし、触れません。アンダースコアを大文字の前に表示するには、独自のロケール設定を定義する必要があります。標準ライブラリだけでロケールの定義を探し、少なくともLinuxでこれは、可能性が、使いにくいです-何もありませんあなたが置くことができるか、環境変数の設定が。valuecmd/usr/lib/locale~/.localeen_tom
ジル 'SO-悪であるのをやめる

@TomAugerこれがlsコマンドだけの場合は、Mikelの提案に従ってください。
ジル 'SO-悪であるのをやめる

2

残念ながら、LinuxはICUではなくロケール情報にglibcを使用しているため、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

6
それがファイルシステムに保存される方法だからです。
イグナシオバスケス-エイブラムス

3
申し訳ありませんが、この答えは間違いです。テスト:touch 3 1 _1 _3 2 _2 && ls -fl出力2 . 1 3 _2 _3 .. _1
マルコ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.