6

次の場合:

$ echo $BASH_VERSION
4.2.10(1)-release

$ shopt | fgrep case
nocaseglob      off
nocasematch     off

$ case A in [a-z]) echo TRUE;; esac
TRUE

大文字のAは[az]の小文字のクラスと一致しないはずですが、一致します。なぜこの試合は失敗しないのですか?

4

2 に答える 2

7

この方法でダッシュを確実に使用することはできません。ダッシュを使用しない場合、期待どおりに機能します。

$ bash --version
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ shopt -s nocasematch
$ case A in [abc]) echo TRUE;; esac
TRUE
$ shopt -u nocasematch
$ case A in [abc]) echo TRUE;; esac
$ 

ただしダッシュを使用すると、の設定に関係なくTRUEが出力されますnocasematch

Bashはここでパターンマッチングを行っています。リファレンスマニュアルのこのセクションをチェックしてください。ハイフンを使用すると、次のように解釈[a-z]される可能性があり[A-Za-z]ます。従来の解釈を取得する方法を説明します(LC_COLLATEまたはLC_ALLをCに設定します)。基本的に、デフォルトのロケールは辞書順にソートされています。リファレンスマニュアルは物事をかなりよく説明しています。

補遺

さて、私はあなたのためにトランスクリプトを持っています。

$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
$ LC_ALL=C
$ shopt -u nocasematch
$ case A in [a-z]) echo TRUE;; esac
$ shopt -s nocasematch
$ case A in [a-z]) echo TRUE;; esac
TRUE
于 2012-05-22T02:43:28.553 に答える
7

それはあなたのロケール設定と関係があります。具体的には、照合シーケンスは大文字と小文字を区別しないシーケンスです。

たとえば、 (私のシステムのデフォルト)にLC_COLLATE設定するen_AU.utf8と、小文字と大文字が一緒に含まれていることがわかります。

pax> case A in [a-b]) echo TRUE;; esac
TRUE
pax> _

ただし、範囲指定子を削除すると、期待どおりに機能します。

pax> case A in [ab]) echo TRUE;; esac
pax> _

これは、最初の手段between a and b inclusiveが、その照合シーケンスに対して、を含むためAです。後者の場合は、照合シーケンスの影響を受ける範囲ではaありbません。

照合シーケンスで大文字と小文字を区別するシーケンスを設定すると、期待どおりに機能します。

pax> export LC_COLLATE="C"
pax> case A in [a-b]) echo TRUE;; esac
pax> 

他に何も影響を与えずに1回限りの操作としてこれを実行したい場合は、サブシェルで実行できます。

( export LC_COLLATE="C" ; case A in [a-b]) echo TRUE;; esac )
于 2012-05-22T02:56:51.917 に答える