変更要約: 初版(主題1.03・副主題1.03.1〜1.03.5に対応)
3.4正規表現を使用したテキストファイルの検索
正規表現によるパターン検索を学びます。主要なメタ文字(^・$・.・*・[ ]・\\)、grep とその仲間(egrep=grep -E・fgrep=grep -F)の違い、sed と組み合わせた検索置換、regex(7) マニュアルの位置づけを押さえます。
「ERROR で始まる行だけ」「数字が続く箇所だけ」— 固定文字列では表せないパターンを記述する言語が正規表現です。ワイルドカード(シェルのグロブ)と似て非なるルールなので、両者の * の意味の違いまで意識して学びます。
3.4.1メタ文字の基本
- 位置=^(行頭)・$(行末)。
^ERRORは「ERROR で始まる行」・^$は空行。 - 文字=.(任意の1文字)・[abc]/[a-z](集合・範囲)・[^abc](否定)。
- 繰り返し=*(直前の要素の0回以上)。
ab*cは ac・abc・abbc に一致。シェルの*(任意文字列)とは意味が違う。 - 拡張正規表現(ERE)=
+(1回以上)・?(0か1回)・|(または)・( )(グループ)がそのまま使える。基本正規表現(BRE)では\+のようにエスケープが要る。メタ文字を文字として使うなら \\ でエスケープ。
3.4.2grep ファミリーと sed
- grep=正規表現に一致する行を表示(
-i大小無視・-v不一致行・-n行番号・-r再帰)。 - egrep(=
grep -E)=拡張正規表現で検索/fgrep(=grep -F)=正規表現を解釈しない固定文字列検索(メタ文字を含む文字列をそのまま探すときに最速・安全)。 - sed の置換=
sed 's/古い/新しい/g'(g で行内すべて)。-nとpで「一致行だけ表示」=grep 的にも使える。正規表現の文法詳細は regex(7) マニュアルにまとまっている。
「^ 行頭・$ 行末・. 任意1文字・* 直前の0回以上」の4点は落とせません。「+ や | を使いたい→ egrep(grep -E)」「メタ文字を検索したい→ fgrep(grep -F)」「一致しない行→ grep -v」の使い分けが定番です。「正規表現の * =シェルの *」と混同させる選択肢に注意。
混同しやすい2つの * を並べて整理しましょう。シェルで ls *.log と打つと、シェルが「任意の文字列+.log」に展開します(グロブ)。一方 grep 'er*or' file の * は直前の r が0回以上という意味で、eor・eror・error に一致します。「任意の文字列」を正規表現で書くなら .*(任意の1文字が0回以上)です。実務の型もいくつか覚えましょう:設定ファイルからコメントと空行を除いて実効行だけ見るのは grep -v '^#' conf | grep -v '^$'、ログから ERROR か WARN を拾うのは egrep 'ERROR|WARN' app.log、IP アドレスのようにドットを文字として探すなら fgrep '192.168.1.1' log(または \. エスケープ)です。sed は「読むだけの grep」から一歩進んで直しながら流す道具=sed 's/http:/https:/g' urls.txt のように、パターン処理の出口としてよく登場します。
| コマンド | 解釈 | 使いどころ |
|---|---|---|
| grep | 基本正規表現(BRE) | 日常の行検索 |
| egrep(grep -E) | 拡張正規表現(+ ? | ( )) | 「または」や回数指定 |
| fgrep(grep -F) | 固定文字列(解釈なし) | メタ文字を含む検索・高速 |
| sed s/// | 正規表現で置換 | 検索して直す |
ひっかけ: 「正規表現の * は任意の文字列に一致する」は誤りです。* は直前の要素の0回以上の繰り返しで、任意文字列は .* と書きます(シェルのグロブとの混同を誘う定番)。また「fgrep は拡張正規表現で検索する」も誤り=fgrep(grep -F)は正規表現を一切解釈しません。
3.4.3この節のまとめ
- ^行頭・$行末・.任意1文字・[ ]集合・\*直前0回以上(任意文字列は .\*)。文法詳細は regex(7)
- grep(BRE)/egrep=-E(拡張)/fgrep=-F(固定文字列)・不一致行は -v・置換は sed s///g
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. ログファイルから「ERROR で始まる行」だけを表示したい。適切なコマンドは?
Q2. 「ERROR または WARN を含む行」を1つのパターンで検索したい。最も適切なコマンドは?
Q3. 設定ファイル中の文字列「192.168.1.1」を、ドットをメタ文字として解釈させずに最速で検索したい。適切なコマンドは?

