Bash の Case ステートメント内で正規表現を実行する
この記事では、正規表現、その基本的な構文、および Bash で case
構造と if-else
構造を使用して正規表現を実行する方法について説明します。
正規表現の紹介
regex
または regexp
とも呼ばれる正規表現は、テキスト/文字列の一致に使用される一連の文字です。 regex
は非常に強力で、大量のデータを解析する必要がある場合に多くの時間を節約できます。
Bash は regex
を使用しませんが、regex
に似た構文の文字列マッチングを使用します。 以下のスクリプトは、Bash との文字列マッチングの基本に慣れるのに役立ちます。
?(a pattern list)
# Matches exactly zero or one instance of the pattern
*(a pattern list)
# This matches zero or more instances of the pattern.
+(a pattern list)
# This matches one or more instances of the pattern.
@(a pattern list)
# This matches one of the enclosed patterns.
!(a pattern list)
# This matches any pattern except the one enclosed.
上記のコード フェンスは、基本的な regex
構文を示しています。 regex
について詳しく知りたい場合は、この リンク にアクセスしてください。
Bash で複雑な文字列マッチングを有効にする必要性
デフォルトでは、Bash で単純な正規表現を実行できます。 複雑な正規表現では、extglob
オプションを有効にする必要があります。 以下のコマンドは、extglob
を有効または無効にして、複雑な正規表現を実行できるようにする方法を示しています。
shopt -s extglob # this command enables extglob and allows the execution of complicated regex
shopt -u extglob # this command disables extglob and disables execution of complicated regex
上記のコマンドの extglob
は、拡張グロビングを表します。 設定されている場合、パス名展開で指定された複雑な/高度なパターン マッチング機能が許可されます。
正規表現が複雑かどうかは、実行しないとわかりません。 extglob
オプションを有効にすると、すべてのコマンドを安心して実行できます。
extglob
がオンかオフかをどのように知るかという質問があるかもしれません。 以下のコマンドを参考にしてください。
shopt | grep extglob # displays status of extglob
出力:
extglob off # displays this line if extglob is disabled
extglob on # displays this line if extglob is enabled
上記のコマンドは、extglob
のステータス (オンかオフか) を表示します。
Case
構造で正規表現を使用した文字列マッチング
文字列マッチング (regex
に似ています) は、case
構造を使用してさらに強力にすることができます。これを使用して、より複雑なデータを解析できるようにすることができます。 以下のコマンドは、Bash で case
を使用して作業します。
case EXPRESSION in
Match_1)
STATEMENTS # run this statement if in matches match_1
;;
Match_2)
STATEMENTS # run this statement if in matches match_2
;;
Match_N)
STATEMENTS # run this statement if in matches match_N
;;
*)
STATEMENTS # otherwise, run this statement
;;
Esac # signals the end of the case statement to the kernel
上記のコードは、Bash 文字列マッチングを case
構造と組み合わせたい場合に使用する一般的な構文です。
デフォルトでは、Bash は単純なパターン マッチングを許可します。 たとえば、以下の Bash コマンドを正常に実行します。
cat sh*
# the above command displays the contents of all files whose name begins #with sh to the monitor (or stdout)
ただし、以下のコマンド (複雑なパターン マッチングを使用) を指定すると、bash: syntax error near unexpected token '('
.
cat +([0-9]) # this command displays contents of files whose names are
# entirely composed of numbers
Bash での文字列マッチングについてさらに詳しく知りたい場合は、以下のコマンドを使用してください。
man bash # man is a short form of manual pages here
マニュアル ページは、Bash コマンド、システム コールなどに関する情報を検索するために使用できるユーティリティです。
Bash で case
との文字列マッチングを使用している場合は、最初にパターンを比較する変数を宣言して定義することをお勧めします。
以下のコマンド スニペットでは、文字列マッチングで case
を使用しました。 文字列照合の基本を使用して、強力な文字列照合アルゴリズムを生成したことに注目してください。
コマンドを見てみましょう。
# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled
some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab-+([0-9])\.host\.com) echo "First 2 characters were ab"
;;
ks-+([0-9])\.host\.com) echo "First 2 characters were ks"
;;
cs-+([0-9])\.host\.com) echo "First 2 characters were cs"
;;
*)echo "unknown first 2 characters"
;;
esac;
# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true
出力:
unknown first 2 characters
上記の文字列一致コマンドを分析すると、最初の 2 文字が (ab
、ks
、cs
) のいずれかであり、次の文字がハイフン (–
) の後に任意の数の数字と末尾が続く場合 .host.com
の場合、最初の 3つのケースのうちの 1つが成功し、適切なメッセージが表示されます。
ただし、そうでない場合は、デフォルト (つまり、それ以外の場合) が実行され、最初の 2 文字が不明です
というメッセージが表示されます。
上記のコマンドが複雑すぎる場合は、より簡単な解決策があります。 以下のコマンドは、その方法を正確に説明しています。
some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab*.host.com) echo "First 2 characters were ab"
;;
# the command below stays the same
上記のコマンドは、上で使用したより複雑なケース構造と同じことを行います。
If-Else
構造で正規表現を使用した文字列マッチング
強力な文字列照合アルゴリズムをコーディングするもう 1つの方法は、それらを if-else
構造と共に使用することです。 これを使用して、より複雑なデータを解析したいと考えています。
次の Bash コマンドは、if-else
構造の構文を順を追って説明します。
if expression1
then
task1
elif expression2
then
task2
else
task3
fi # signals ending of if else structure
if-else
構造の操作は簡単です。 まず、最初の式を評価します。
true
の場合、タスク 1
を実行します。 それ以外の場合は、2 番目の式を検討します。
true
の場合、タスク 2
を実行します。 それ以外の場合は task3
を実行します。
if-else
構造の構文に慣れてきたので、case
構造で使用されるコマンドを同等の if-else
構造に複製しましょう。 それを行うには、以下のコマンドを参照してください。
# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled
some_variable="rs-123.host.com"; # declare and define variable
if expr "$some_variable" : ‘ab-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ab"
elif expr "$some_variable" : ‘ks-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ks"
elif expr "$some_variable" : ‘cs-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were cs"
else echo "unknown first 2 characters"
fi
# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true
出力:
unknown first 2 characters
上記のコマンドは、以前に使用した case
構造に相当する if-else
です。