角かっこワイルドカードの大文字と小文字の区別

角かっこワイルドカードの大文字と小文字の区別

通常、bashワイルドカードは大文字と小文字を区別します。

$ echo c*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo C*
CarePackage.md ChocRippleCake.md Clips

角かっこを使っても変更されないようです。

$ echo [c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C]*
CarePackage.md ChocRippleCake.md Clips

ハイフンを使用しても変更されません。

$ echo [c-c]*
casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py
$ echo [C-C]*
CarePackage.md ChocRippleCake.md Clips

しかし、手紙は散らばっています。

$ echo [B-C]*
CarePackage.md casefix.pike cdless chalices.py charconv.py chocolate.pike ChocRippleCake.md circum.py clip.pike Clips cpustats.pike crop.pike cwk2txt.py
$ echo [b-c]*
beehive-anthem.txt bluray2mkv.pike branch branchcleanup.pike burdayim.pike casefix.pike cdless chalices.py charconv.py chocolate.pike circum.py clip.pike cpustats.pike crop.pike cwk2txt.py

これは、ハイフンが「AaBbCcDd」ロケール順序を使用していることを示します。それでは、大文字で始まるすべてのファイルをワイルドカードとして指定する方法はありますか?

答え1

Bash 4.3以降には、次のshoptオプションがありますglobasciiranges

~によるとshopt 組み込み GNU のマニュアルページ:

globasciiranges
設定されている場合、パターンマッチング角括弧式(パターンマッチングを参照)で使用される範囲式は、比較を実行するときに既存のCロケールと同様に機能します。つまり、現在のロケールの組み合わせ順序を考慮していないので、「A」と「B」の間では「b」は対照的ではありませんが、ASCII大文字と小文字は一緒に対照されます。

できることがわかりました

$ shopt -s globasciiranges 
$ echo [A-Z]*

無効にしますshopt -u

別の方法は、ロケールをCに変更することです。サブシェルを使用して一時的にこれを実行できます。

$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )

所望の結果が得られ、サブシェルが完了すると、メインシェルのロケールは以前と同じままです。

別のオプションは、bash shoptオプションと一緒に中括弧拡張を使用しないことです[A-Z]{A..Z}nullglob

このオプションを有効にすると、nullglobパス名拡張中にパターンが一致しない場合、パターン自体の代わりに空の文字列が返されます。
その結果、期待どおりに動作します。

$ shopt -s nullglob;printf '%s\n' {A..Z}*

答え2

次のように、すべて大文字を書くことができます。

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

または、名前付き文字クラスを使用して[:upper:]現在のすべての大文字を表すことができますlocale

[[:upper:]]*

ご存知のように、範囲(たとえば、[B-C]同じアルファベット文字の大文字と小文字)を使用すると、互いに並べ替えられます(の組み合わせ規則に従ってlocale)。

答え3

文字範囲に「直感的でない」文字(大文字で囲まれた範囲の小文字など)を含めるのは、LC_COLLATEロケール設定によるものです。LC_COLLATEはソート順序を示す必要がありますが、正しく機能せず(文字列ソートはロケールで実行できるよりも複雑です)、それを使用しない方が良いでしょう。LC_COLLATEあなたのロケールから削除することをお勧めします。LANG、またはを設定するには、これを行わずに必要LANGUAGEなものだけを設定してください:LC_CTYPE、、、。LC_MESSAGESLC_TIME

ロケールの設定に関する詳細な背景については、次をご覧ください。ロケールを何に設定する必要がありますか?これはどのような影響を及ぼしますか?そしてLC_*を設定しますが、LC_ALLは設定しません

ユーザーの設定に関係なく、スクリプトから信頼できる結果を得るには、を設定しますLC_ALL=C

答え4

echo [cC]* は、[A-Za-z]* などの目的の操作を実行する必要があります。

私のシステムのワイルドカード停止大文字と小文字が区別されるため、多くのスクリプトが正しく機能しなくなります。 :-(

関連情報