grepで検索する
前提:3-3が完了し、~/practiceの中にfruits.txt(りんご・みかん・ぶどうの3行)、copy.txt(同内容)、memo.txt、vimtest.txtが存在する状態から始めます。ファイルの中身が長くなればなるほど、人間の目で欲しい情報を探すのは大変になります。そこで登場するのがgrepです。このページでは3-3で作ったfruits.txtを検索しながら基本の使い方を覚え、最後は第2章で作ったyumiユーザーを/etc/passwdの中から探し出して、これまでの物語とつなげます。
このページではSET 1〜3、合計30行のコマンドを上から順に叩きます。手打ち推奨(コピーは確認用)です。
SET 1 ― grepの基本と -i -n
- $cd ~/practice
- $ls
- copy.txt fruits.txt memo.txt vimtest.txt
- $cat fruits.txt
- りんご
- みかん
- ぶどう
- $wc -l fruits.txt
- 3 fruits.txt
- $grep みかん fruits.txt
- みかん
- $grep メロン fruits.txt
- $grep -n みかん fruits.txt
- 2:みかん
- $grep ん fruits.txt
- みかん
- $grep -n ん fruits.txt
- 2:みかん
- $which grep
- /usr/bin/grep
1行目で練習用ディレクトリへ移動し、2行目のlsで、3-3までに作った4つのファイルがそろっていることを確認しておきます。
3行目のcatでfruits.txtの中身を見直し、4行目のwc -lで行数が3であることも数値で確認しておきます。5行目のgrep みかん fruits.txtが基本の形です。grep(global regular expression printの略)は「検索したい文字列」と「探す対象のファイル」を指定すると、その文字列を含む行だけを画面に表示してくれるコマンドです。fruits.txtの3行のうち「みかん」を含む行だけが、出力例のとおり抜き出されています。
6行目のように、ファイルの中に存在しない文字列(メロン)を検索すると、エラーにはならず何も表示されずにプロンプトへ戻るだけです。これは「該当なし」を意味する正常な結果なので、慌てる必要はありません。
7行目の-nオプションを付けると、一致した行の内容だけでなく、それが何行目だったかも一緒に表示されます。出力例の2:みかんは「2行目にみかんという行があった」という意味で、コロンの前が行番号です。長いログファイルの中から該当箇所を探すとき、この行番号があるとあとで見返すのに便利です。
8行目のgrep ん fruits.txtのように検索文字列は単語だけでなく1文字でもよく、「ん」を含む行として「みかん」だけが引っかかります(「りんご」「ぶどう」には「ん」が含まれません)。9行目のように-nを組み合わせても同じ考え方です。10行目のwhich grep(第1章で学んだコマンドの場所を調べるコマンド)で、grepが/usr/bin/grepにインストール済みであることも確認しておきましょう。

grepは「探しているキーワード、ファイルの中にある?」って聞いてる感じのコマンドだよ。あって当然、なくても当然。エラーだと思って焦らなくて大丈夫!
SET 2 ― -i -v -c で探し方を変える
- $echo "Apple" >> fruits.txt
- $cat fruits.txt
- $wc -l fruits.txt
- 4 fruits.txt
- $grep apple fruits.txt
- $grep -i apple fruits.txt
- Apple
- $grep -in apple fruits.txt
- 4:Apple
- $grep -v みかん fruits.txt
- りんご
- ぶどう
- Apple
- $grep -c "" fruits.txt
- $grep -c みかん fruits.txt
- $grep -vc みかん fruits.txt
1行目でfruits.txtに英単語「Apple」(大文字A始まり)を追記し、2行目のcatで確認します。3行目のwc -lで行数が4になったことも数値で確認しておきましょう。5行目のように小文字のappleで検索すると、grepは大文字と小文字を区別するため何も見つかりません。ここで6行目のように-iオプション(ignore caseの意味)を付けると、大文字・小文字の違いを無視して検索するようになり、出力例のとおり「Apple」がヒットします。
7行目のようにgrep -inと1文字ずつつなげて書くと、-i(大文字小文字無視)と-n(行番号表示)を同時に効かせられます。出力例の4:Appleは「4行目にApple」という意味で、複数のオプションを1つにまとめて使えることがわかります。
8行目の-vオプションは、これまでとは逆に「指定した文字列を含まない行だけ」を表示します(invert matchの意味)。「みかん」を含まない行を検索すると、出力例のとおり「りんご」「ぶどう」「Apple」の3行が返ってきます。欲しくない情報を除外して見たいときに重宝します。
9行目のgrep -c "" fruits.txtの-cオプション(countの意味)は、一致した行の内容ではなく一致した行数だけを数字で返します。検索文字列に空文字""を指定しているのは「どんな行にも一致する」という意味で、結果としてファイルの全行数が数字で返ってきます。中身を見ずに件数だけ知りたいときに便利なオプションです。10行目のように具体的な文字列「みかん」を指定すれば一致件数(1)だけが返り、11行目のように-vと-cを組み合わせた-vcにすると、「みかんを含まない行」の件数(3)を一気に数えられます。
-i=大文字小文字を無視、-n=行番号を出す、-v=一致しない行を出す、-c=件数だけ出す。組み合わせて使うこともでき、たとえばgrep -ivのように1文字ずつつなげて書けます。
SET 3 ― -r で複数ファイル検索、/etc/passwdでyumiを探す
- $grep みかん *.txt
- fruits.txt:みかん
- copy.txt:みかん
- $grep -l みかん *.txt
- fruits.txt
- copy.txt
- $grep -r みかん ~/practice
- $wc -l /etc/passwd
- $cat /etc/passwd
- $grep yumi /etc/passwd
- yumi:x:1001:1001::/home/yumi:/bin/bash
- $grep -n yumi /etc/passwd
- $grep -c yumi /etc/passwd
- 1
- $grep ubuntu /etc/passwd
- $cd ~
1行目のgrep みかん *.txtでは、ファイル名の代わりに*.txtという書き方をしています。*(アスタリスク)は「任意の文字列」を表すワイルドカード※1で、*.txtは「拡張子が.txtのすべてのファイル」を意味します。複数ファイルを対象にすると、出力例のとおりファイル名:一致した行という形式で、どのファイルの結果かも一緒に表示されます。
2行目の-lオプション(小文字のエル。listの意味)は、一致した行の中身ではなく一致したファイル名だけを一覧表示します。出力例のとおり、fruits.txtとcopy.txtのどちらに「みかん」が含まれているかが、ファイル名だけでシンプルにわかります。
3行目の-rオプション(recursiveの意味)は、指定したディレクトリの中身をサブディレクトリも含めてすべて検索します。*.txtのようにファイルの種類を指定しなくても、ディレクトリ以下をまるごと対象にできる強力なオプションです。
4行目のwc -l /etc/passwdで、これから検索する/etc/passwdが何行あるファイルなのかをあらかじめ数値で確認しておきます。5行目のcat /etc/passwdで、第2章2-2で見た「Linuxに存在する全ユーザーの台帳」の中身をあらためて眺めます。6行目のgrep yumi /etc/passwdで、大量の行の中から第2章で作ったyumiユーザーの情報だけを一発で抜き出せます。出力例のようにyumi:x:1001:1001::/home/yumi:/bin/bashという行が見つかれば、yumiが今もこのサーバーに存在していることの証拠です。7行目のように-nを付ければ、それが全体の何行目にあるかもわかります。8行目の-cを付けると、yumiという文字列を含む行が全体で1行だけであることも数値で確認できます。9行目では自分自身のubuntuユーザーも同じように検索し、最後に10行目でホームディレクトリへ戻ります。

/etc/passwdの中にちゃんとあたしの名前見つけてくれてありがとう! grepって、何百行もあるファイルの中から一瞬で欲しい行だけピンポイントで探し出せるから、サーバー管理の現場だと数えきれないくらい使う機会があるコマンドだよ。今のうちに指に覚え込ませておいてね!
まとめ
3-4では、ファイルの中から目的の文字列を検索するgrepコマンドと、その動きを変える代表的なオプションを一通り体験しました。このページで叩けるようになったコマンドを一覧にまとめます。
| コマンド | 何をするか | 覚え方 |
|---|---|---|
grep 文字列 ファイル | 文字列を含む行だけを表示する | ファイルの中身をふるいにかける |
grep -i | 大文字・小文字を区別せず検索する | ignore case |
grep -n | 一致した行の行番号も表示する | number(番号) |
grep -v | 指定した文字列を含まない行を表示する | invert(逆転) |
grep -c | 一致した行数だけを表示する | count(数える) |
grep -r | ディレクトリ以下を再帰的に検索する | recursive(再帰的) |
次のページ「3-5. テキスト加工ツール」では、検索した結果をさらに並べ替えたり重複を除いたりする、sortやuniqといった加工系コマンドを体験します。
- ワイルドカード …
*のように「任意の文字列」を表す特殊な記号。*.txtは拡張子が.txtのすべてのファイルを意味する。↩