角括弧グロビングにおける大文字と小文字の区別


10

通常、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」を使用していることを示唆しています。だから:大文字で始まるすべてのファイルをグロブする方法はありますか?


3
また、[AZ]は 'z'を除くすべての小文字に一致することに注意してください。
PJTraill 2017年

回答:


12

bashバージョン4.3以降では、shoptオプションが呼び出されますglobasciiranges

shopt builtin gnu manページによると:

globasciiranges
設定されている場合、パターンマッチングの括弧式(パターンマッチングを参照)で使用される範囲式は、比較を実行するときに従来のCロケールであるかのように動作します。つまり、現在のロケールの照合シーケンスは考慮されないため、「b」は「A」と「B」の間で照合されず、大文字と小文字のASCII文字が一緒に照合されます。

結果として、

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

shopt -u無効にするために使用します。

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

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

必要な結果が得られ、サブシェルが終了しても、メインシェルのロケールは以前のものに変更されません。

別の選択肢は、bash shoptオプションと一緒に[A-Z]ブレース展開を使用する代わりです。{A..Z}nullglob

このnullglobオプションを有効にすると、パス名の展開中にパターンが一致しない場合、パターン自体ではなくnull文字列が返されます。
その結果、これは期待どおりに機能します。

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

2
パーフェクト、ありがとう。[[:upper:]]実際にはアルファベットの一部しか必要ないので使用できませんが、これでうまくいきます。
rosuav 2017年

1
@rosuavようこそ。サブシェルの代替案も確認してください。
George Vasiliou 2017年

「有効になっている場合はCロケールと等しい」 -グロビングに使用されるロケールのみに影響するということですか?(参照リンクは役に立ちました-私が見つけることができる最高のものはgnu.org/software/bash/manual/html_node/Pattern-Matching.htmlですが、すべてのシェルオプションのリストを優先したいと思いますが、globasciirangesがありませんgnu.org/software/bash/manual/html_node/…から。また、質問unix.stackexchange.com/questions/227070/…がこの問題を広範囲に処理します。)バージョン4.3から。
PJTraill 2017年

@PjTrailすべてのshoptオプションへの参照リンクを含む編集内容を参照してください。またman bash、ターミナルで実行し、/globasciirangesを(を使用して)検索できます。
George Vasiliou 2017年

LC_ALL=C printf '%s\n' [A-Z]*サブシェルがないと、2番目のソリューションでは機能しませんか?ところで:タイプミスがあります:nullblogが、それを修正するには文字数が少なすぎます。
Joe

5

すべて大文字で書くことができます:

[ABCDEFGHIJKLMNOPQRSTUVWXYZ]*

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

[[:upper:]]*

お気づきのように[B-C]、同じアルファベットの大文字と小文字のような範囲を使用している間、(の照合順序に従って)隣接して配置されていますlocale


3

境界が大文字である範囲に小文字を含めるなど、文字範囲に「直感的でない」文字を含めるのは、LC_COLLATEロケール設定が原因です。LC_COLLATEソート順を示すことになっていますが、それはうまく機能しません(文字列のソートは、ロケールが実行できるものよりも複雑です)。LC_COLLATEロケール設定から削除することをお勧めします。あなたのしている設定の場合LANG、またはLANGUAGE、それを行うと、あなたが必要なものだけを設定していません:LC_CTYPELC_MESSAGESLC_TIME

ロケールの背景については、「ロケールを何に設定すればよいですか?」を参照してくださいLC_ *設定しますが、LC_ALLは設定しません

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


0

セットする:

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文字がどうなるかわかりません。


0

echo [cC] *は同様に[A-Za-z] *を実行します。

私のシステムでのグロビングは大文字と小文字が区別されるのをやめたため、ここにいます。つまり、私のスクリプトのロードは、本来のように機能しません:-(


それは私が見ているものの逆です。ただし、他の回答で提案を確認してください。
rosuav
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.