正規表現とは・基本のメタ文字
正規表現は「文字列のパターン」を表す書き方で、検索や置換を一気に行えます。多くの文字はそのままの意味ですが、特別な働きを持つ文字を「メタ文字」と呼びます。基本は任意の1文字を表す . 、直前の繰り返しを表す * 、行頭を表す ^ 、行末を表す $ の4つです。例えば ^a は行頭の a、b$ は行末の b、a.c は a と c の間に任意の1文字が挟まる並びを指します。まずはこの4つに慣れることが出発点です。
ファイル一覧やログの中から「特定の語で始まる行」「末尾が .conf の行」「数字の並び」といった、ひと言では指しにくい条件を、記号の組み合わせで正確に言い表す書き方が正規表現です。目で一行ずつ追って探すのに比べ、条件さえ式にできれば何百行・何千行でも一瞬でふるい分けられます。たとえば「error または Error を含む行」を一つの式で書けるので、人間が見落としがちな大文字小文字の違いも取りこぼしません。Linuxのテキスト処理は、この正規表現を grep・sed・awk といったコマンドに渡して回すのが土台になっており、まずはパターンを書く感覚を身につけることが、後のすべての応用につながります。最初は記号が暗号のように見えますが、覚えるべき基本はごく少数です。
正規表現の中で、特別な働きを持つ記号のことをメタ文字と呼びます。a や 5 のようなふつうの文字は、その文字そのものを表します。これに対してメタ文字は「任意の1文字」「直前のくり返し」「行頭」「行末」といった、文字そのものではなく構造や位置を表します。逆に言えば、メタ文字でない文字はすべて「書いたとおりの文字」として素直にマッチするので、まずはどの記号がメタ文字なのかを押さえるのが近道です。ここで紹介するのは grep や sed が標準で使う基本正規表現(BRE)の書き方で、後の項目で出てくる拡張正規表現(ERE)とは一部の記号の扱いが違いますが、最初の土台としては BRE を体に入れるのが順当です。
まず覚える4つの基本メタ文字
最初の出発点は . * ^ $ の4つです。. (ドット)は改行以外の任意の1文字にマッチします。a.c と書けば、a と c のあいだに何か1文字が挟まる並びを指し、abc や a5c などに一致します。* は直前の文字の0回以上のくり返しを表し、ab* は a だけの場合も含めて a, ab, abb, abbb… のいずれにも一致します。ここで注意したいのは、* は「直前の1文字」に対して効く、という点です。ab* は「ab のくり返し」ではなく「a のあとに b が0個以上」という意味になります。くり返したいまとまりが複数文字のときは、後の項目で学ぶグループ化が必要になります。
残る ^ と $ は、文字ではなく「位置」を指すのが特徴で、これをアンカーと呼びます。^ は行頭の位置に、$ は行末の位置に一致します。^a は「a で始まる行」、b$ は「b で終わる行」という意味になり、^a.c$ なら「a で始まり、任意の1文字を挟んで c で終わる、ちょうど3文字の行」を表します。アンカーは何かの文字に当たるのではなく、行の端という見えない場所に当たる、という点を最初に飲み込んでおくと、後で混乱しません。たとえば ^root を grep に渡すと、行のどこかに root があるだけの行ではなく、行頭が root の行だけが選ばれます。同じ要領で、^abc$ と書けば「中身がちょうど abc だけの行」を、^$ と書けば「中身が何もない空行」を指せます。アンカーを使いこなせると、行のどこに語があるかまで含めて狙えるようになり、検索の精度が大きく上がります。
記号そのものを探したいとき — エスケープ
. や * のようなメタ文字を、記号そのものとして探したいときは、直前にバックスラッシュ \ を付けて意味を打ち消します。これをエスケープといいます。たとえば \. は「任意の1文字」ではなく「文字としてのドット」を表します。末尾が .conf の行を抜き出したいときに grep '\.conf$' と書くのはこのためで、もし \ を付けずに grep '.conf$' とすると、ドットが任意の1文字として働き、aconf や xconf のような行まで拾ってしまいます。「特別な意味を消したいときは \ を付ける」と覚えてください。逆に、ただの文字である a や 1 に \ を付ける必要はありません。
クォートで囲むのが鉄則
正規表現を扱ううえで、最初に身につけたい習慣がもう一つあります。それは、パターンを必ずシングルクォート '…' で囲むことです。* ? $ といった記号は、コマンドに届く前にシェルがファイル名展開(グロブ)や変数として先に解釈してしまうことがあり、意図しない結果やエラーを招きます。'…' で囲めば、これらの記号はそのまま grep などに渡されます。たとえば ls /etc | grep '\.conf$' は、/etc の一覧のうち末尾が .conf の行だけを残し、chrony.conf や resolv.conf のような行が一致します。クォートを外すと $ がシェル変数として解釈されたり、* がカレントディレクトリのファイル名に展開されたりして、パターンが壊れてしまいます。
よくある失敗と実務の使いどころ
初学者がつまずきやすいのは、^ と $ を「文字」と勘違いすることと、メタ文字のエスケープを忘れることです。a$ は「a という文字のあとにドル記号」ではなく「a で終わる行」であり、IPアドレスの 192.168.0.1 を探すつもりで grep '192.168.0.1' と書くと、ドットが任意の1文字として働き 19208680a1 のような並びにも当たり得ます。厳密に探すなら grep '192\.168\.0\.1' とエスケープします。もう一つの定番の混乱は、* を「何にでも当たる万能記号」と思い込むことです。* はあくまで直前の文字のくり返しを表すだけで、それ単体では何も指しません。ファイル名で見慣れた * とは意味が違う、と早めに切り分けておきましょう。実務では、設定ファイルから ^# でコメント行を、^$ で空行を指して読み飛ばす、特定の語で始まる行や終わる行だけを抜き出す、といった場面でこの4つが絶え間なく登場します。まずは「. は任意の1文字、* はくり返し、^ と $ は行頭・行末のアンカー、記号そのものは \ で打ち消し、式は ' で囲む」——この最小セットを手に馴染ませることが、正規表現・メタ文字・アンカーを使いこなす第一歩になります。