通常、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」を使用していることを示唆しています。だから:大文字で始まるすべてのファイルをグロブする方法はありますか?
Bashバージョン4.3以降には、globasciiranges
というshoptオプションがあります。
globasciiranges
設定すると、パターンマッチングの括弧式(パターンマッチングを参照)で使用される範囲式は、比較を実行するときに従来のCロケールであるかのように動作します。つまり、現在のロケールの照合シーケンスは考慮されないため、「b」は「A」と「B」の間で照合されず、大文字と小文字のASCII文字は一緒に照合します。
結果として、
$ shopt -s globasciiranges
$ echo [A-Z]*
無効にするにはshopt -u
を使用します。
別の方法は、ロケールをCに変更することです。これは、サブシェルを使用して一時的に行うことができます。
$ ( LC_ALL=C ; printf '%s\n' [A-Z]*; )
必要な結果が得られ、サブシェルが終了しても、メインシェルのロケールは以前と同じままです。
もう1つの方法は、[A-Z]
の代わりに、ブレース展開{A..Z}
をnullglob
bashショップオプションと共に使用することです。
nullglob
オプションを有効にすると、パス名の展開中にパターンが一致しない場合、パターン自体ではなくnull文字列が返されます。
その結果、これは期待どおりに機能します:
$ shopt -s nullglob;printf '%s\n' {A..Z}*
すべて大文字で書くことができます:
[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*
または、名前付き文字クラス[:upper:]
を使用して、現在のlocale
のすべての大文字を表すことができます。
[[:upper:]]*
お気づきのとおり、[B-C]
のような範囲を使用している間、同じアルファベット文字の大文字と小文字は(locale
の照合順序に従って)隣接して配置されています。
境界が大文字である範囲に小文字を含めるなど、「直感的でない」文字を文字範囲に含めるのは、LC_COLLATE
ロケール設定が原因です。 LC_COLLATE
は並べ替え順序を示すことになっていますが、これはうまく機能せず(文字列の並べ替えは、ロケールで可能なことよりも複雑です)、それなしで使用することをお勧めします。ロケール設定からLC_COLLATE
を削除することをお勧めします。 LANG
、またはLANGUAGE
を設定する場合は、これを行わず、必要なものだけを設定してください:LC_CTYPE
、LC_MESSAGES
、LC_TIME
。
ロケールの背景については、 ロケールを何に設定すればよいですか、そうすることの意味は何ですか? および LC_ALLではなくLC_ *を設定 を参照してください。
ユーザーの設定に関係なくスクリプトで信頼できる結果を得るには、LC_ALL=C
を設定します。
セットする:
shopt -u nocaseglob
Bashのmanページから:
> nocaseglob
> If set, bash matches filenames in a case-insensitive
> fashion when performing pathname expansion (see Pathname
> Expansion above).
'globasciiranges'を設定した場合、utf-8のような非ASCII文字がどうなるかわかりません
echo [cC] *は同様に[A-Za-z] *を実行します。
私のシステムでのグロビングはstoppedで大文字と小文字が区別されるため、ここにいます。つまり、スクリプトのロードは、本来あるべきように機能しません:-(