さびたシェルスクリプトのスキルを復活させようとしていますが、caseステートメントで問題が発生しました。以下のプログラムでの私の目標は、ユーザーが指定した文字列が大文字で始まるか小文字で始まるかを評価することです。
# practicing case statements
echo "enter a string"
read yourstring
echo -e "your string is $yourstring\n"
case "$yourstring" in
[A-Z]* )
echo "your string begins with a Capital Letter"
;;
[a-z]* )
echo "your string begins with a lowercase letter"
;;
*)
echo "your string did not begin with an English letter"
;;
esac
myvar=nope
case $myvar in
N*)
echo "begins with CAPITAL 'N'"
;;
n*)
echo "begins with lowercase 'n'"
;;
*)
echo "hahahaha"
;;
esac
小文字で始まる文字列(引用符なしの「mystring」など)を入力すると、caseステートメントは入力を最初の大文字と一致させ、文字列が大文字で始まることを通知します。2番目のcaseステートメントを記述して、明らかな構文エラーまたは論理エラーが発生していないかどうかを確認しました(おそらく私はまだそうです)が、同じ問題は発生していません。2番目の大文字と小文字の構造は、$ myvarが保持する文字列が小文字で始まることを正しく示しています。
引用符を使用してcaseステートメントの最初の行で$ yourstringを囲んでみましたが、引用符なしで試しました。'shopt'オプションについて読み、 'nocasematch'がオフになっていることを確認しました。(念のため、オンに切り替えて再試行しましたが、最初のcaseステートメントから正しい結果が得られませんでした。)shとbashを使用してスクリプトを実行しようとしましたが、出力は同じです。(実行ビットを設定しなかったため、「sh./case1.sh」と「bash./case1.sh」を使用してシェルを明示的に呼び出します。ファイルを複製して新しいファイルに実行ビットを設定しても、出力は変更されませんでした。 。)
'-x'デバッグオプションを使用してシェルを実行した場合のすべての出力を理解しているわけではありませんが、出力には、シェルが最初の「case」行から最初のパターンに続くコマンドの実行まで進行していることが示されています。これは、最初のパターンが入力文字列と一致したことを意味すると解釈しますが、理由はわかりません。
最初の2つのパターン(および対応するコマンド)の順序を切り替えると、caseステートメントは小文字で成功しますが、「MYSTRING」が小文字で始まると誤って報告されます。アルファベットが最初に表示されたパターンに一致するものとして検出されるため、論理エラーがあると思います...しかし、何がわからないのです。
unix.comで「pludi」による投稿を見つけました。「小文字と大文字のテストは[az]と[AZ]でした。これは、特定のロケールやLinuxディストリビューションでは機能しなくなりました。」(https://www.unix.com/shell-programming-and-scripting-128929-example-switch-case-bash.htmlを参照)もちろん、文字範囲を[[:upper:]]と[[ :lower:]]問題を解決しました。
私はFedora31を使用しており、ロケール出力は次のとおりです。
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
文字範囲を理解していないのか、caseステートメントでパターンマッチングがどのように機能するのかを理解していないのか、または基盤となるシェル機能が変更されたのか(そしてその理由は?)を知りたいのですが。忍耐力があれば、説明をいただければ幸いです。関連するドキュメントも読んでうれしいです。ありがとう!
簡単な答え、間違いなく他の人が取って代わることができるもの。
文字セットの順序は、使用されているロケールによって異なります。ロケールの概念は、さまざまな国籍とさまざまな言語をサポートするために導入されました。の出力からわかるように、locale
照合だけでなく、現在対処されているいくつかの異なる領域があります。
あなたの場合、それは米国であり、ソートと照合の目的で、アルファベットはAaBbCc ... ZzまたはA = a、B = b、C = cなどのいずれかです(どちらかを忘れており、私はコンピューターを使用していません。私は一方を他方の上に確認することができます)。ロケールは非常に複雑であり、特定のロケールでは、並べ替えと照合に関する限り、文字が表示されない場合があります。同じ文字は、使用されているロケールに応じて異なる方法でソートできます。
お気づきのとおり、小文字を識別する正しい方法は[[:lower:]]
;を使用することです。これには、必要に応じてアクセント付き文字が含まれ、さまざまなアルファベット(ギリシャ文字、キリル文字など)の小文字も含まれます。
従来の順序が必要な場合は、を設定することで、アプリケーションごと、またはコマンドごとに戻すことができますLC_ALL=C
。不自然な例として、
grep some_pattern | LC_ALL=C sort | nl
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加