正規表現を使用して、パターンに基づいてテキストを検索および操作します。 Linux コマンドとプログラミング言語のほとんどは、正規表現を使用しています。
grep コマンドは、ファイル内の特定の文字列を検索するために使用されます。 15 の実用的な grep コマンドの例については、以前の記事を参照してください。
特定のパターンを含むテキストを検索する場合は、grep コマンドで正規表現を使用することもできます。正規表現は、ファイルの各行でパターンを検索します。これにより、検索操作が簡素化されます。
この記事は 2 つの記事シリーズの一部です。
このパート 1 の記事では、単純な正規表現の grep の例について説明します。今後のパート 2 の記事では、grep での高度な正規表現の例について説明します。
例で使用する /var/log/messages ファイルを見てみましょう。
例 1. 行頭 ( ^ )
grep コマンドでは、キャレット記号 ^ が行頭の式に一致します。次の例では、11 月 10 日に始まるすべての行が表示されます。つまり、11 月 10 日に記録されたすべてのメッセージです。
$ grep "^Nov 10" messages.1 Nov 10 01:12:55 gs123 ntpd[2241]: time reset +0.177479 s Nov 10 01:17:17 gs123 ntpd[2241]: synchronized to LOCAL(0), stratum 10 Nov 10 01:18:49 gs123 ntpd[2241]: synchronized to 15.1.13.13, stratum 3 Nov 10 13:21:26 gs123 ntpd[2241]: time reset +0.146664 s Nov 10 13:25:46 gs123 ntpd[2241]: synchronized to LOCAL(0), stratum 10 Nov 10 13:26:27 gs123 ntpd[2241]: synchronized to 15.1.13.13, stratum 3
^ は、正規表現の最初の文字である場合にのみ、行頭の式に一致します。 ^N は、N で始まる行に一致します。
例 2. 行末 ( $)
文字 $ は、行末の式に一致します。次のコマンドは、「terinating」という単語で終わるすべての行を取得するのに役立ちます。
$ grep "terminating.$" messages Jul 12 17:01:09 cloneme kernel: Kernel log daemon terminating. Oct 28 06:29:54 cloneme kernel: Kernel log daemon terminating.
上記の出力から、すべてのカーネル ログがいつ終了したかを知ることができます。 ^ が最初の文字である場合にのみ行頭に一致するように、$ は正規表現の最後の文字である場合にのみ行末に一致します。
例 3. 空行の数 ( ^$ )
^ および $ 文字を使用すると、ファイル内で使用可能な空の行を見つけることができます。 「^$」は空行を指定します。
$ grep -c "^$" messages anaconda.log messages:0 anaconda.log:3
上記のコマンドは、メッセージと anaconda.log ファイルで利用可能な空行の数を表示します。
例 4. 1 文字 (.)
特殊なメタ文字「.」 (ドット) は、行末文字を除く任意の文字に一致します。次のような内容の入力ファイルを見てみましょう。
$ cat input 1. first line 2. hi hello 3. hi zello how are you 4. cello 5. aello 6. eello 7. last line
任意の 1 文字の後に ello が続く単語を検索してみましょう。こんにちは、チェロなど
$ grep ".ello" input 2. hi hello 3. hi zello how are you 4. cello 5. aello 6. eello
4 文字しかない単語を検索したい場合は、grep -w “….” を指定できます。ここで、1 つのドットは任意の 1 文字を表します。
例 5. 0 回以上の出現 (*)
特殊文字「*」は、前の文字の 0 回以上の出現に一致します。たとえば、パターン「1*」はゼロ個以上の「1」に一致します。
次の例では、パターン「kernel:*」、つまり kernel:および 0 個以上の空白文字の出現を検索します。
$ grep "kernel: *." * messages.4:Jul 12 17:01:02 cloneme kernel: ACPI: PCI interrupt for device 0000:00:11.0 disabled messages.4:Oct 28 06:29:49 cloneme kernel: ACPI: PM-Timer IO Port: 0x1008 messages.4:Oct 28 06:31:06 btovm871 kernel: sda: sda1 sda2 sda3 messages.4:Oct 28 06:31:06 btovm871 kernel: sd 0:0:0:0: Attached scsi disk sda . .
上記の例では、カーネルとコロン記号の後に任意の数のスペース/スペースなしと「.」が続く場合に一致します。
例 6. 1 つ以上のオカレンス (\+)
特殊文字「\+」は、前の文字の 1 つ以上の出現と一致します。 ” \+” は、少なくとも 1 つ以上の空白文字と一致します。
スペースがない場合は一致しません。文字「+」は拡張正規表現に属します。そのため、grep コマンドで使用する場合はエスケープする必要があります。
$ cat input hi hello hi hello how are you hihello $ grep "hi \+hello" input hi hello hi hello how are you
上記の例では、grep パターンはパターン「hi」に一致し、その後に 1 つ以上のスペース文字が続き、その後に「hello」が続きます。
こんにちはとこんにちはの間にスペースがない場合、それは一致しません。ただし、* 文字は 0 回以上の出現に一致します。
以下に示すように、「hihello」は * と一致します。
$ grep "hi *hello" input hi hello hi hello how are you hihello $
例 7. 0 回または 1 回の出現 (\?)
特殊文字「?」前の文字の 0 回または 1 回の出現に一致します。 「0?」単一のゼロまたはゼロに一致します。
$ grep "hi \?hello" input hi hello hihello
“hi \?hello” は、単一スペース (hi hello) およびスペースなし (hihello) の hi と hello に一致します。
hi と hello の間に複数のスペースがある行は、上記のコマンドで一致しませんでした.
例 8.特殊文字 (\) のエスケープ
コンテンツで特殊文字 (例:* 、ドット) を検索する場合は、正規表現で特殊文字をエスケープする必要があります。
$ grep "127\.0\.0\.1" /var/log/messages.4 Oct 28 06:31:10 btovm871 ntpd[2241]: Listening on interface lo, 127.0.0.1#123 Enabled
例 9. 文字クラス ([0-9])
文字クラスは、複数の文字のうちの 1 つだけに一致するために使用される角括弧で囲まれた文字のリストに他なりません。
$ grep -B 1 "[0123456789]\+ times" /var/log/messages.4 Oct 28 06:38:35 btovm871 init: open(/dev/pts/0): No such file or directory Oct 28 06:38:35 btovm871 last message repeated 2 times Oct 28 06:38:38 btovm871 pcscd: winscard.c:304:SCardConnect() Reader E-Gate 0 0 Not Found Oct 28 06:38:38 btovm871 last message repeated 3 times
繰り返されるメッセージは、「n 回繰り返された最後のメッセージ」としてメッセージ ログ ファイルに記録されます。上記の例では、任意の数字 (0 から 9) の後に "times" という単語が続く行を検索します。一致する場合は、一致した行の前の行と一致した行も表示します。
角括弧内にハイフンを使用して、文字の範囲を指定できます。 [0123456789] のように [0-9] で表すことができます。 [a-z]、[A-Z] などのようにアルファベットの範囲も指定できます。したがって、上記のコマンドは次のようにも記述できます
$ grep -B 1 "[0-9]\+ times" /var/log/messages.4
例 10. 文字クラスの例外
角括弧内の文字を除くすべての文字を検索する場合は、開始角括弧の後の最初の文字として ^ (キャレット) 記号を使用します。次の例は、Linux の辞書単語ファイルから母音文字で始まらない行を検索します。
$ grep -i "^[^aeiou]" /usr/share/dict/linux.words 1080 10-point 10th 11-point 12-point 16-point 18-point 1st 2
正規表現の最初のキャレット記号は行頭を表します。ただし、角括弧内のキャレット記号は「除く」を表します。つまり、角括弧内のすべてを除いて一致します。