通常、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_MESSAGES
LC_TIME
ロケールの設定に関する詳細な背景については、次をご覧ください。ロケールを何に設定する必要がありますか?これはどのような影響を及ぼしますか?そしてLC_*を設定しますが、LC_ALLは設定しません
ユーザーの設定に関係なく、スクリプトから信頼できる結果を得るには、を設定しますLC_ALL=C
。
答え4
echo [cC]* は、[A-Za-z]* などの目的の操作を実行する必要があります。
私のシステムのワイルドカード停止大文字と小文字が区別されるため、多くのスクリプトが正しく機能しなくなります。 :-(