Bash での正規表現マッチング

ShellShellBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

このチュートリアルでは、Bash での正規表現 (regex) について紹介します。正規表現は、テキスト内のパターンを見つけるための強力なツールです。正規表現を学ぶことで、シェルスクリプトのスキルが大幅に向上し、テキストの処理、データの抽出、タスクの自動化をより効果的に行うことができるようになります。このチュートリアルは初心者向けに設計されているため、正規表現の事前知識は必要ありません。基本から始めて、徐々に知識を深めていきます。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL shell(("Shell")) -.-> shell/SystemInteractionandConfigurationGroup(["System Interaction and Configuration"]) shell(("Shell")) -.-> shell/VariableHandlingGroup(["Variable Handling"]) shell(("Shell")) -.-> shell/ControlFlowGroup(["Control Flow"]) shell(("Shell")) -.-> shell/AdvancedScriptingConceptsGroup(["Advanced Scripting Concepts"]) shell/VariableHandlingGroup -.-> shell/variables_decl("Variable Declaration") shell/VariableHandlingGroup -.-> shell/variables_usage("Variable Usage") shell/VariableHandlingGroup -.-> shell/str_manipulation("String Manipulation") shell/ControlFlowGroup -.-> shell/if_else("If-Else Statements") shell/ControlFlowGroup -.-> shell/cond_expr("Conditional Expressions") shell/AdvancedScriptingConceptsGroup -.-> shell/cmd_substitution("Command Substitution") shell/SystemInteractionandConfigurationGroup -.-> shell/globbing_expansion("Globbing and Pathname Expansion") subgraph Lab Skills shell/variables_decl -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/variables_usage -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/str_manipulation -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/if_else -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/cond_expr -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/cmd_substitution -.-> lab-391551{{"Bash での正規表現マッチング"}} shell/globbing_expansion -.-> lab-391551{{"Bash での正規表現マッチング"}} end

基本的な正規表現とマッチングの理解

正規表現の基本概念から始めましょう。正規表現は、検索パターン を定義する文字の並びです。これを非常に強力なテキスト検索方法と考えてください。

以下は基本的な構成要素です。

  • リテラル文字: ほとんどの文字はそれ自身と一致します。たとえば、正規表現 abc は文字列 "abc" と正確に一致します。
  • メタ文字: これらは正規表現で特定の意味を持つ特殊文字です。いくつかの重要なものを見てみましょう。
    • . (ドット): 任意の単一文字 (改行を除く) と一致します。したがって、a.c は "abc"、"axc"、"a1c" などと一致します。
    • * (アスタリスク): 直前の文字を 0 回以上 繰り返したものと一致します。ab*c は "ac"、"abc"、"abbc"、"abbbc" などと一致します。
    • ^ (キャレット): 行の先頭 と一致します。^hello は "hello" で始まる行と一致します。
    • $ (ドル記号): 行の末尾 と一致します。world$ は "world" で終わる行と一致します。
    • [] (角括弧): 文字クラス を定義します。括弧内の文字の いずれか 1 つ と一致します。[abc] は "a"、"b"、または "c" と一致します。[0-9] は任意の単一の数字と一致します。

では、理解をテストするために Bash スクリプトを作成しましょう。touch コマンドを使用して regex_test.sh という名前のファイルを作成します。

cd ~/project
touch regex_test.sh

次に、テキストエディタ (nanovim など) で regex_test.sh を開き、以下のコードを追加します。

#!/bin/bash

string="Hello World"
if [[ "$string" =~ ^Hello ]]; then
  echo "The string starts with Hello"
else
  echo "The string does not start with Hello"
fi

ファイルを保存し、実行可能にします。

chmod +x regex_test.sh

最後に、スクリプトを実行します。

./regex_test.sh
Regex and Matching

出力は、文字列が "Hello" で始まることを示すはずです。

スクリプトでの文字セットの使用

角括弧 [] を使って定義される文字セットを使用すると、特定のグループから 1 文字を一致させることができます。これは、より柔軟なパターンを作成するのに非常に便利です。

  • 文字範囲: [] の中では、ハイフン (-) を使って範囲を指定できます。[a-z] は任意の小文字と一致し、[A-Z] は任意の大文字と一致し、[0-9] は任意の数字と一致します。これらを組み合わせることもできます。[a-zA-Z0-9] は任意の英数字と一致します。
  • 否定: [] の中の 最初の 文字として ^ を置くと、その文字クラスを 否定 します。[^0-9] は数字 以外 の任意の文字と一致します。

文字セットを使用するように regex_test.sh スクリプトを変更しましょう。テキストエディタで regex_test.sh を開き、その内容を以下のものに置き換えます。

#!/bin/bash

string="cat"
if [[ "$string" =~ c[a-z]t ]]; then
  echo "Match found!"
else
  echo "No match."
fi

ファイルを保存して実行します。

./regex_test.sh

出力は "Match found!" を示すはずです。これは、c[a-z]t が 'c' で始まり 't' で終わり、中間の文字が小文字である 3 文字の文字列と一致するためです。

スクリプトで量指定子を使ったパターンの繰り返し

量指定子 (Quantifier) は、文字やグループが何回繰り返されるかを制御します。これにより、正規表現パターンの機能が大幅に拡張されます。

  • + (プラス): 直前の文字を 1 回以上 繰り返したものと一致します。ab+c は "abc"、"abbc"、"abbbc" などと一致しますが、"ac" とは 一致しません
  • ? (疑問符): 直前の文字を 0 回または 1 回 繰り返したものと一致します (つまり、直前の文字をオプションにします)。ab?c は "ac" と "abc" と一致しますが、"abbc" とは一致しません。
  • * (アスタリスク): 直前の文字を 0 回以上 繰り返したものと一致します。これは前に説明しました。
  • {n}: 直前の文字を正確に n 回 繰り返したものと一致します。a{3} は "aaa" と一致します。
  • {n,}: 直前の文字を n 回以上 繰り返したものと一致します。a{2,} は "aa"、"aaa"、"aaaa" などと一致します。
  • {n,m}: 直前の文字を n 回から m 回 (両端を含む) 繰り返したものと一致します。a{1,3} は "a"、"aa"、または "aaa" と一致します。

量指定子を使用するように regex_test.sh スクリプトを変更しましょう。テキストエディタで regex_test.sh を開き、その内容を以下のものに置き換えます。

#!/bin/bash

string="abbbc"
if [[ "$string" =~ ab+c ]]; then
  echo "Match found!"
else
  echo "No match."
fi

ファイルを保存して実行します。

./regex_test.sh

出力は "Match found!" を示すはずです。これは、ab+c が 'a' で始まり、1 つ以上の 'b' が続き、'c' で終わる文字列と一致するためです。

スクリプトでキャプチャグループを使ったデータ抽出

括弧 () は、正規表現の一部を グループ化 するために使用されます。これは、複数の文字に量指定子を適用したり、一致したテキストを キャプチャ したりするのに便利です。

括弧を使用すると、Bash は正規表現のその部分に一致したテキストを BASH_REMATCH という特殊な配列に格納します。BASH_REMATCH[0] には一致した文字列全体が格納され、BASH_REMATCH[1] には最初のグループに一致したテキストが、BASH_REMATCH[2] には 2 番目のグループに一致したテキストが格納され、以下同様です。

キャプチャグループを使用してデータを抽出するように regex_test.sh スクリプトを変更しましょう。テキストエディタで regex_test.sh を開き、その内容を以下のものに置き換えます。

#!/bin/bash

string="apple123"
if [[ "$string" =~ ^([a-z]+)([0-9]+)$ ]]; then
  fruit="${BASH_REMATCH[1]}"
  number="${BASH_REMATCH[2]}"
  echo "Fruit: $fruit"
else
  echo "No match."
fi

ファイルを保存して実行します。

./regex_test.sh

出力には "Fruit: apple" が含まれるはずです。このスクリプトは、キャプチャグループを使用して文字列から果物の名前を抽出します。

スクリプトで sed を使ったテキスト置換

sed の使用を練習するために、sed_test.sh という新しいスクリプトを作成しましょう。

cd ~/project
touch sed_test.sh
chmod +x sed_test.sh

テキストエディタで sed_test.sh を開き、以下を追加します。

#!/bin/bash

string="apple123"
echo "$string" | sed 's/[0-9]/X/g'

ファイルを保存して実行します。

./sed_test.sh

出力は appleXXX となるはずです。このスクリプトは sed を使用して、文字列内のすべての数字を文字 "X" に置き換えます。

まとめ

このチュートリアルでは、Bash での正規表現 (regex) について紹介しました。基本的な正規表現の概念、文字クラス、量指定子、グルーピング、キャプチャ、および sed で正規表現を使用する方法を学びました。Bash スクリプトを記述して実行することで、これらの強力なツールを実際に使った経験を積むことができました。理解を深めるために、さまざまな正規表現パターンを使って練習や実験を続けることを忘れないでください。