Grep と正規表現: それらを効果的に使用するにはどうすればよいですか?

Grep と正規表現: それらを効果的に使用するにはどうすればよいですか?

Linux をしばらく使用している場合は、ファイルやディレクトリの検索に使用できるテキスト処理ツールである grep (Global Regular Expression Print) についてはすでにご存知でしょう。 Linux パワー ユーザーにとっては非常に便利です。ただし、正規表現を使用せずに使用すると、機能が制限される可能性があります。

しかし、正規表現とは何でしょうか?

Regex は、grep 検索機能を向上させるために使用できる正規表現です。正規表現は、定義上、高度な出力フィルタリング パターンです。練習すれば、他の Linux コマンドでも正規表現を使用できるため、正規表現を効果的に使用できるようになります。

このチュートリアルでは、Grep と Regex を効果的に使用する方法を学びます。

前提条件

正規表現で grep を使用するには、Linux に関する十分な知識が必要です。初心者の方は、Linux ガイドをご覧ください。

Linux オペレーティング システムを実行しているラップトップまたはコンピューターへのアクセスも必要です。任意の Linux ディストリビューションを使用できます。また、Windows マシンをお持ちの場合は、引き続き WSL2 で Linux を使用できます。詳細については、こちらをご覧ください。

コマンド ライン/ターミナルにアクセスすると、grep/regex チュートリアルで提供されるすべてのコマンドを実行できます。

さらに、例を実行するために必要なテキスト ファイルへのアクセスも必要です。 ChatGPT を使用してテキストの壁を生成し、テクノロジーについて書くように指示しました。私が使用したプロンプトは以下のとおりです。

「テクノロジーに関して 400 語を生成します。ほとんどのテクノロジーが含まれているはずです。また、テキスト全体でテクノロジー名を繰り返すようにしてください。」

テキストが生成されたら、それをコピー&ペーストして tech.txt ファイルに保存しました。このファイルはチュートリアル全体で使用します。

最後に、grep コマンドの基本を理解することが必須です。 16 個の grep コマンドの例をチェックして、知識をリフレッシュしてください。開始するために grep コマンドについても簡単に紹介します。

grepコマンドの構文と例

grepコマンドの構文は単純です。

 $ grep -options [regex/pattern] [files]

ご覧のとおり、コマンドを実行するパターンとファイルのリストが必要です。

その機能を変更する利用可能な grep オプションが多数あります。これらには次のものが含まれます。

  • – i: 大文字と小文字を区別しない
  • -r:再帰的検索を実行します
  • -w:単語全体のみを検索する検索を実行します。
  • -v:一致しない行をすべて表示します
  • -n:一致する行番号をすべて表示します。
  • -l:ファイル名を出力します。
  • –color:色付きの結果出力
  • -c:使用されたパターンの一致数を表示します

#1.単語全体を検索する

単語全体を検索するには、grep で -w 引数を使用する必要があります。これを使用すると、指定されたパターンに一致する文字列をバイパスできます。

 $ grep -w ‘tech\|5G’ tech.txt 

ご覧のとおり、このコマンドの出力では、テキスト全体で「5G」と「tech」という 2 つの単語が検索されます。次に、それらを赤色でマークします。

ここで、 |パイプ記号は grep がメタキャラクターとして処理しないようにエスケープされます。

大文字と小文字を区別しない検索を行うには、 -i引数を指定して grep を使用します。

 $ grep -i ‘tech’ tech.txt 

このコマンドは、単語全体でも一部でも、大文字と小文字を区別せずに「tech」文字列のインスタンスを検索します。

指定されたパターンを含まないすべての行を表示するには、 -v引数を使用する必要があります。

 $ grep -v ‘tech’ tech.txt 

出力には、「 tech 」という単語を含まないすべての行が表示されます。また、空の行も表示されます。これらの行は段落の後の行です。

再帰的検索を行うには、grep で-r引数を使用します。

 $ grep -R ‘error\|warning’ /var/log/*.log
 #output

/var/log/bootstrap.log:2023-01-03 21:40:18 URL:http://ftpmaster.internal/ubuntu/pool/main/libg/libgpg-error/libgpg-erro 0_1.43-3_amd64.deb [69684/69684] -> "/build/chroot//var/cache/apt/archives/partial/libgpg-error0_1.43-3_amd64.deb" [1]

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 5 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: parsing file '/var/lib/dpkg/status' near line 24 package 'dpkg':

/var/log/bootstrap.log:dpkg: warning: ignoring pre-dependency problem! 
grep 再帰検索ログ ファイル
grep 再帰検索ログ ファイル

grep コマンドは、/var/log ディレクトリ内で「error」と「warning」という 2 つの単語を再帰的に検索します。これは、ログ ファイル内の警告やエラーを確認するのに便利なコマンドです。

Grep と正規表現: その概要と例

ここでは正規表現を使用しているため、正規表現には 3 つの構文オプションがあることを知っておく必要があります。これらには次のものが含まれます。

  • 基本的な正規表現 (BRE)
  • 拡張正規表現 (ERE)
  • Pearl 互換正規表現 (PCRE)

grep コマンドは、デフォルト オプションとして BRE を使用します。したがって、他の正規表現モードを使用したい場合は、それらについて言及する必要があります。 grep コマンドはメタキャラクターもそのまま扱います。したがって、?、+、) などのメタ文字を使用する場合は、バックスラッシュ (\) コマンドでエスケープする必要があります。

正規表現を使用した grep の構文は次のとおりです。

 $ grep [regex] [filenames]

以下の例で grep と regex が実際に動作する様子を見てみましょう。

#1.リテラルの単語の一致

リテラルの単語の一致を行うには、文字列を正規表現として指定する必要があります。結局のところ、単語も正規表現です。

 $ grep "technologies" tech.txt 
リテラル単語は grep 正規表現と一致します
リテラル単語は grep 正規表現と一致します

同様に、リテラル一致を使用して現在のユーザーを検索することもできます。そのためには、走って、

 $ grep bash /etc/passwd
 #output

root:x:0:0:root:/root:/bin/bash

nitt:x:1000:1000:,,,:/home/nitt:/bin/bash 
grep regex bash 現在のユーザー
grep regex bash 現在のユーザー

これにより、bash にアクセスできるユーザーが表示されます。

#2.アンカーマッチング

アンカー マッチングは、特殊文字を使用した高度な検索に便利なテクニックです。正規表現では、テキスト内の特定の位置を表すために使用できるさまざまなアンカー文字があります。これらには次のものが含まれます。

  • ^’ キャレット記号:キャレット記号は入力文字列または入力行の先頭と一致し、空の文字列を検索します。
  • $’ ドル記号:ドル記号は入力文字列または入力行の末尾と一致し、空の文字列を検索します。

他の 2 つのアンカー一致文字には、’\ b’ 単語境界と ‘\ B’ 非単語境界が含まれます。

  • ‘\ b’ 単語境界: \b を使用すると、単語と単語以外の文字の間の位置を主張できます。簡単に言えば、完全な単語を一致させることができます。こうすることで、部分一致を回避できます。これを使用して、単語を置換したり、文字列内の単語の出現をカウントしたりすることもできます。
  • \B 非単語境界:これは、2 単語または非単語文字の間ではない位置を主張するため、正規表現における \b 単語境界の逆です。

明確なアイデアを得るために例を見てみましょう。

 $ grep ‘^From’ tech.txt 
grep キャレットアンカー
grep キャレットアンカー

キャレットを使用するには、単語またはパターンを大文字と小文字を正しく入力する必要があります。大文字と小文字が区別されるためです。したがって、次のコマンドを実行しても、何も返されません。

 $ grep ‘^from’ tech.txt

同様に、$ 記号を使用して、特定のパターン、文字列、または単語に一致する文を検索できます。

 $ grep ‘technology.$' tech.txt 
grepドルアンカー
grepドルアンカー

^ 記号と $ 記号の両方を組み合わせることもできます。以下の例を見てみましょう。

 $ grep “^From \| technology.$” tech.txt 
grep キャレット ドル
grep キャレット ドル

ご覧のとおり、出力には「From」で始まる文と「technology」で終わる文が含まれています。

#3.グループ化

複数のパターンを一度に検索したい場合は、グループ化を使用する必要があります。これは、単一の単位として扱うことができる文字やパターンの小さなグループを作成するのに役立ちます。たとえば、「t」、「e」、「c」、「h」という用語を含むグループ (tech) を作成できます。

明確なアイデアを得るために、例を確認してみましょう。

 $ grep 'technol\(ogy\)\?' tech.txt 
grep グループ化の例
grep グループ化の例

グループ化を使用すると、繰り返されるパターンを照合し、グループをキャプチャし、代替を検索できます。

グループ化による代替検索

代替検索の例を見てみましょう。

 $ grep "\(tech\|technology\)" tech.txt 
grep代替検索
grep代替検索

文字列に対して検索を実行する場合は、パイプ記号を使用して文字列を渡す必要があります。以下の例で見てみましょう。

 $ echo “tech technological technologies technical” |  grep "\(tech\|technology\)"
 #output

“tech technological technologies technical” 
grep検索文字列
grep検索文字列

キャプチャ グループ、非キャプチャ グループ、および繰り返しパターン

そして、捕獲グループと非捕獲グループはどうなるでしょうか?

正規表現でグループを作成し、それを文字列またはグループをキャプチャするファイルに渡す必要があります。

 $ echo 'tech655 tech655nical technologies655 tech655-oriented 655' | grep "\(tech\)\(655\)"
 #output

tech655 tech655nical technologies655 tech655-oriented 655 
grep キャプチャ グループ
grep キャプチャ グループ

また、非キャプチャ グループの場合は、括弧内で ?: を使用する必要があります。

最後に、繰り返しのパターンがあります。繰り返しのパターンをチェックするには、正規表現を変更する必要があります。

 $ echo ‘teach tech ttrial tttechno attest’ | grep '\(t\+\)'
 #output

‘teach tech ttrial tttechno attest’

ここで、正規表現は「t」文字の 1 つ以上のインスタンスを検索します。

#4.文字クラス

文字クラスを使用すると、正規表現を簡単に作成できます。これらの文字クラスでは角括弧が使用されます。よく知られている文字クラスには次のようなものがあります。

  • [:digit:] – 0 ~ 9 桁
  • [:alpha:] – アルファベット文字
  • [:alnum:] – 英数字
  • [: lower:] – 小文字
  • [:upper:] – 大文字
  • [:xdigital:] – 0 ~ 9、AF、AF を含む 16 進数
  • [:blank:] – タブやスペースなどの空白文字

等々!

いくつかの動作を確認してみましょう。

 $ grep [[:digit]] tech.txt 
grep 数字文字クラスの例
grep 数字文字クラスの例
 $ grep [[:alpha:]] tech.txt 
grep アルファベット文字クラスの例
grep アルファベット文字クラスの例
 $ grep [[:xdigit:]] tech.txt 
grep xdigital 文字クラスの例
grep xdigital 文字クラスの例

#5.数量指定子

量指定子はメタ文字であり、正規表現の中核です。これらにより、外観を正確に一致させることができます。以下でそれらを見てみましょう。

  • * → 0 個以上の一致
  • + → 1 つ以上の一致
  • ? → 0 または 1 が一致
  • {x} → x が一致
  • {x, } → x 個以上の一致
  • {x,z} → x から z までの一致
  • {, z} → 最大 z 個の一致
$ echo ‘teach tech ttrial tttechno attest’ | grep -E 't+'
 #output

‘teach tech ttrial tttechno attest’

ここでは、「 t」文字インスタンスを検索して、1 つ以上の一致を探します。ここで、-E は拡張正規表現を表します (これについては後で説明します)。

量指定子 grep
量指定子 grep

#6.拡張正規表現

正規表現パターンにエスケープ文字を追加したくない場合は、拡張正規表現を使用する必要があります。これにより、エスケープ文字を追加する必要がなくなります。これを行うには、-E フラグを使用する必要があります。

 $ grep -E 'in+ovation' tech.txt 
拡張正規表現
拡張正規表現

#7。 PCRE を使用した複雑な検索の実行

PCRE (Perl 互換正規表現) を使用すると、基本的な式を作成する以上のことができます。たとえば、[0-9] を表す「\d」と書くことができます。

たとえば、PCRE を使用して電子メール アドレスを検索できます。

 echo "Contact me at nitish@newdomain.com" | grep -P "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b"
 #output

Contact me at nitish@newdomain.com 
PCREメールの例
PCREメールの例

ここで、PCRE はパターンが一致することを確認します。同様に、PCRE パターンを使用して日付パターンを確認することもできます。

 $ echo "The Sparkain site launched on 2023-07-29" | grep -P "\b\d{4}-\d{2}-\d{2}\b"
 #output

The Sparkain site launched on 2023-07-29 
PCREの日付
PCREの日付

このコマンドは、 YYYY-MM-DD形式で日付を検索します。他の日付形式と一致するように変更することもできます。

#8.交代

別の一致が必要な場合は、エスケープされたパイプ文字 (\|) を使用できます。

 $ grep -L ‘warning\|error’ /var/log/*.log
 #output

/var/log/alternatives.log

/var/log/bootstrap.log

/var/log/dpkg.log

/var/log/fontconfig.log

/var/log/ubuntu-advantage.log

/var/log/upgrade-policy-changed.log

出力には、「警告」または「エラー」を含むファイル名がリストされます。

ログファイルのスクリーンショット。
ログファイルのスクリーンショット。

最後の言葉

これで grep と正規表現のガイドは終わりです。 grep と正規表現を幅広く使用して、検索を絞り込むことができます。正しく使用すると、時間を大幅に節約し、多くのタスクの自動化に役立ちます。特にスクリプトを作成するために使用したり、テキストの検索を実行する際に正規表現を使用したりする場合に役立ちます。

次に、Linux 面接でよくある質問と回答を確認してください。

「 Grep と正規表現: それらを効果的に使用するにはどうすればよいですか?」についてわかりやすく解説!絶対に観るべきベスト2動画

grep を使用してファイル内のパターンを検索する
Learning grep for Linux, OS X and Unix