文字列検索 grep
1,000 行を目で追うのをやめる
サーバーのログや設定ファイルは、たいてい人が読み切れない長さです。cat で開いて目で探すやり方は、行数が三桁を超えたあたりで成立しなくなります。
たとえば nginx の設定ファイルは、コメントを含めると数百行あります。どのポートで待ち受けているのかを確かめたいだけなのに、全部を目で追うのは割に合いません。
grep は、指定した文字を含む行だけを取り出します。
ターミナル
$ grep listen /etc/nginx/nginx.conf
listen 80;
listen [::]:80;ファイル名を省くと、パイプで渡された内容から探します。前のレッスンでつないだ流れの途中に置けます。
ターミナル
$ ls /usr/bin | grep zip
bunzip2
gunzip
unzip
zipgrep は行を単位に判定します。探している文字がその行のどこかにあれば行を丸ごと通し、無ければ捨てる。やっているのはそれだけです。だから出力は必ず元のファイルにあった行そのままの形になり、あとから元の場所を追いかけられます。
大文字で書かれた行だけ取りこぼす
次のファイルから alice の行を探します。
ターミナル
$ cat /tmp/members.txt
Alice
bob
CAROL
alice
$ grep alice /tmp/members.txt
aliceAlice が出てきません。grep は大文字と小文字を別の文字として扱うためです。同じ語が場所によって違う書き方をされているのはよくあることで、片方だけ見て「無かった」と判断してしまいます。
-i を付けると、大文字と小文字の違いを無視して探します。
ターミナル
$ grep -i alice /tmp/members.txt
Alice
aliceどの行にあったのか分からない
見つけた行を直しにいくには、それが何行目なのかが要ります。-n を付けると行番号が付きます。
ターミナル
$ grep -n CAROL /tmp/members.txt
3:CAROLエディタで 3 行目に飛べば、その行にたどり着けます。
ログを追うときは、まず広く取ってから絞るほうが速く進みます。いきなり正確なパターンを書こうとすると、0 件だったときに探しているものが無いのか、書き方が違うのかを区別できません。まず 1 語で引いて、多すぎたら条件を足す。この順にすれば、どこかで必ず手応えが返ってきます。
何も出ないときは、探す文字を 1 文字か 2 文字に減らして試してください。それでも 0 件なら、開いているファイルのほうが違います。
課題
- echo でテストデータを作る
- grep -i を使う
- ERROR と error の行を 2 行抽出する