Bash の Case ステートメント内で正規表現を実行する

Abdullah Bukhari 2023年6月20日
  1. 正規表現の紹介
  2. Bash で複雑な文字列マッチングを有効にする必要性
  3. Case 構造で正規表現を使用した文字列マッチング
  4. If-Else 構造で正規表現を使用した文字列マッチング
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

bash で複雑な文字列マッチングを有効にする

上記のコマンドは、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

extglob無効時のエラー

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 文字が (abkscs) のいずれかであり、次の文字がハイフン () の後に任意の数の数字と末尾が続く場合 .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

if else で正規表現を使用した文字列マッチング

上記のコマンドは、以前に使用した case 構造に相当する if-else です。

関連記事 - Bash Regex