grepコマンドと正規表現によるファイル内検索
次に、指定したファイルの中から検索文字列を含んでいる行を抽出するgrep
コマンドを説明します。
viでも/
や?
で検索できましたが、あくまでviの機能ですので、viでファイルを開いているときにしか使えません。grep
コマンドはviで開かなくても使えることはもちろんのこと、柔軟で多彩な検索が行えるため非常によく使われます。
ここでは検索対象ファイルとして、先ほど作成したtest.txtファイルを使います。viで編集して、内容を次のように変更しておいてください。
abcdef 123456 12ab34 ab56cd
grepの基本
ではさっそく、grep
コマンドを使ってみましょう。構文は次のとおりです。
grep '検索文字列' 検索ファイル名
grep
コマンドを実行すると、検索ファイルから検索文字列を検索し、マッチした行を表示します。例えば、test.txtファイルに対し「ab」という文字列をgrep
で検索すると、次のようになります。
# grep 'ab' test.txt abcdef 12ab34 ab56cd
test.txtから「ab」を含んでいる行が抽出されました。
その文字を含む/その文字以外の文字を含む行の検索
grep
の優れているところは、検索文字列に正規表現を使用できるところです。正規表現では、例えば「数字3桁が含まれている文字列」や「aから始まる文字列」というような文字列の構成パターンを記述できます。grep
はこの文字列の構成パターンを条件として、検索を行うことができるのです。
次に示すのは、[34ef]
という正規表現を使ってtest.txtを検索する例です。[34ef]
という正規表現は、「3、4、e、fのいずれか1文字が含まれている」という文字列の構成パターンを表します。
# grep '[34ef]' test.txt abcdef 123456 12ab34
一方で、検索条件にマッチしない「ab56cd」の行は表示されていません。
大括弧[ ]
は、「その中に記入されたいずれかの文字を含む」というパターンを表します。「いずれかの数字1文字を含む」というパターンは[0-9]
と書けます。grep
コマンドでの検索例を見てみましょう。
# grep '[0-9]' test.txt 123456 12ab34 ab56cd
[ ]
の中では、半角マイナスを使って「この文字からこの文字までのいずれかの1文字」というパターンを記述できます。上記の場合は「0から9まで(=数値)」ということになります。そのため、アルファベットしかないだけ行は表示されていません。
いずれか1文字とは逆に、「これらの文字以外の1文字」というパターンも[ ]
を使って記述できます。[ ]
の中の先頭に^
(キャレット)を置きます。次の検索例を見てください。
# grep '[^0-9]' test.txt abcdef 12ab34 ab56cd
0から9までの文字以外の文字が入っている行が抽出されています。数字しかない「123456」の行は抽出されていません。
検索位置の指定(行の先頭/末尾)
検索ではよく、「行の先頭が○○」「行の末尾が△△」という条件を使います。grep
コマンドの正規表現では、行の先頭を^
(キャレット)、行の末尾を$
(ドル記号)で表します。^
は、先ほど[ ]
での検索でも使いましたが意味が異なります。
検索例を見てみましょう。次のgrep
コマンドで指定されている正規表現^[0-9]
は、「行の先頭が数字1文字」という検索条件を表しています。
# grep '^[0-9]' test.txt 123456 12ab34
一方、次のgrep
コマンドで指定されている正規表現[0-9]$
は、「行の末尾が数字1文字」という検索条件を表しています。
# grep '[0-9]$' test.txt 123456 12ab34
正規表現は組み合わせて使うこともできます。例えば、「行の先頭が数字以外の文字」という正規表現は^[^0-9]
と書けます。
# grep '^[^0-9]' test.txt abcdef ab56cd
直線の文字の繰り返し回数を指定する正規表現
正規表現で{ }
記号を使うと、その直前にある文字の繰り返し回数を指定できます。例えば、[0-9]{6}
という正規表現は「6桁の数字を含む(数字が6回続けて出現する)」という行にマッチします。
ただし、{ }
はgrep
コマンドの基本正規表現では対応していません。拡張正規表現に当たります。-E
オプションを指定するとgrep
コマンドの正規表現で使うことができます。
# grep -E '[0-9]{6}' test.txt 123456
grepコマンドのバリエーション
-E
オプション付きのgrep
コマンドと同じ動きをするコマンドとして、egrep
コマンドがあります。上記のgrep
コマンドはegrep
コマンドを使うと次のように書けます。
# egrep '[0-9]{6}' test.txt
逆に、正規表現を一切使わないgrep
コマンドもあります。fgrep
です。正規表現に使われる^
や$
、[ ]
などの記号を通常の文字列として検索したい場合にはfgrep
コマンドを使いましょう。
sedコマンドによる正規表現を使った文字列の置換
grep
コマンドは正規表現を利用して文字列を検索できました。ここで紹介するsed
コマンドは、正規表現により検索しマッチした文字列を置換できるコマンドです。sed
コマンドの基本構文は次のとおりです。
sed -e "s/置換前文字列/置換後文字列/g" 対象ファイル
具体例を見てみましょう。次のsed
コマンドは、数字(0~9)をすべて「N」に置換しています。
# sed -e "s/[0-9]/N/g" test.txt abcdef NNNNNN NNabNN abNNcd
注意点として、sed
コマンドはtest.txtの内容を読み出し、s/[0-9]/N/g
という指定に従って置換を実行しましたが、test.txtの内容を書き換えたわけではありません。置換した結果が画面に表示されるのみです。
もう1つ、sed
コマンドの実行例を見てみましょう。
# sed -E "s/^[a-z]+//g" test.txt 123456 12ab34 56cd
+
は「直前にある文字が1文字以降ある」というパターンを表します。ここでは[a-z]
の直後にあるので、「aからzまでの文字が1文字以上ある」というパターンになります。+
は拡張正規表現に含まれるので、grep
コマンドと同じく-E
オプションを指定しています。
また、このsed
コマンドでは置換後文字列が何もありません。この場合、置換前文字列のパターンにマッチした部分は削除されることになります。つまり、aからzまで(つまり小文字のアルファベット)が1文字以上並んでいる部分を削除する、という置換が行われます。
このように、正規表現を使うことでより、複雑な文字列の検索や置換が行えるようになります。考え方に馴染むまで難しいのですが、LPIC受験対策に限らず、現場でも便利この上ないものです。grep
コマンドとsed
コマンドの使い方と合わせてしっかりマスターしましょう。