Linux/UNIX系のOSには「パイプ」と呼ばれる機能が実装されており、多くのコマンドはこのパイプを使ってフィルタとして動作するようになっている。もう少し詳しく説明すると、パイプは「pipe(2)」と呼ばれるシステムコールを使って実現されるIPC(プロセス間通信)機能の1つで、データを一方通行で送信できるという特徴を持っている。
プロセス間通信の方法はいくつかあり、パイプと似てはいても、一方通行のデータストリームではなく、より複雑な機能が実装されているものもある。しかし、現在広く使われているのは、かなりシンプルなパイプだ。結局、この単純なインタフェースや考え方が、利用価値の高い方法だったということなのだろう。
例えば、「command1 | command2」という記述は、「command1」の出力結果が「command2」の入力データとなることを表す。「|」が、パイプを表現する記号だ。「command1 | command2 | command3 | command4」のようにどんどんつなぐことができ、データを加工する場合などに利用することが多い。
利用率が高いフィルタ系コマンド - grep(1)、sed(1)、awk(1)、tr(1)
このようにフィルタ的に動作させることができるコマンドは、Linux/UNIX系のOSにはたくさん用意されている。特に利用率が高いフィルタ系のコマンドは「grep(1)」「sed(1)」「awk(1)」「tr(1)」などだ。いずれも、フィルタリングや置換、任意の加工などができるコマンドである。これらのコマンドの利用スキルは、そのままサーバの操作スキルと言ってもいい。これらコマンドを使いこなせると、日々の業務は一気に楽になる。
awk(1)は汎用プログラミング言語にもなっており、使うには「パターン・アクション」というawk(1)独自の考え方を理解する必要がある。わかってしまえば簡単なのだが、いきなり覚えるのは難しいだろう。sed(1)も似たようなことができるのだが、awk(1)ほど複雑なことはできない。
この中ではtr(1)が最も簡単だが、tr(1)は利用する場面がgrep(1)やawk(1)、sed(1)と比べると少ない。というわけで、まずはそれなりに簡単に利用できて、かつ利用できる幅が広いgrep(1)から覚えるのがお薦めだ。
簡単・便利なgrep(1)の使い方
grep(1)は、フィルタという言葉そのままのコマンドだ。引数にパターンを与えると、そのパターンに一致したデータのみを出力する。-vオプションを指定すると、逆にパターンに一致したデータのみを出力させないといったこともできる。
データの抜き出しは、デフォルトでは行単位となっている。最も簡単な例としては、「ログデータをチェックして、『ERROR』という文字列が含まれている行のみを取り出す」といった使い方が考えられるだろう。例えば、こんな感じだ。
cat /var/log/《何らかのログデータ》 | grep ERROR
grep(1)コマンドに指定できるパターンには、「正規表現」と呼ばれる表記を使用できる。これが魔法の呪文のようで慣れるまでは一苦労なのだが、使いこなせばさまざまな条件を表現できるため、かゆいところに手が届くような指定を行えるようになる。
正規表現を全て正確に覚えるのは大変なので、よく使う記述の中で、覚えやすいものだけ覚えておけばよいと思う。今回は、最も簡単な指定方法を紹介しておく。まずはこのあたりは使えるようになっておこう。
覚えておきたい正規表現
grep(1)の最もシンプルな使い方は、「指定したキーワードを含む行を表示させる」というものだ。grep(1)の引数に、キーワード(パターン)を指定して実行するだけでよい。-vオプションを指定すると、逆にそのキーワード(パターン)を含む行を表示しないようになる。この2つは、基本中の基本だ。
コマンド |
意味 |
grep PATTERN |
PATTERNが含まれている行を表示 |
grep -v PATTERN |
PATTERNが含まれていない行を表示 |
grep ^PATTERN |
行の先頭がPATTERNになっている行を表示 |
grep PATTERN$ |
行の末尾がPATTERNになっている行を表示 |
grep -v ^$ |
空行を削除 |
もう1つ覚えておきたいのが、行頭を表現する「^」と、行末を表現する「$」だ。指定するキーワード(パターン)を「^PATTERN」のように指定すれば、行頭がその文字列(この場合、PATTERN)になっている行がヒットする。一方、「PATTERN$」と指定すれば、行末がこのキーワード(パターン)になっているものに一致する。ということは、「^$」と指定すれば空行を指定しているのと同じことになる。
「^」と「$」を覚えるだけでも、grep(1)でできることは飛躍的に増加する。ログファイルのみならず、ほかのコマンドの出力結果を絞り込む場合などにも便利だ。
例えば、ls(1)コマンドは「ls -l」のように実行するとファイルやディレクトリの一覧を詳細表示させることができる。このls(1)コマンドの出力結果をディレクトリのみに絞り込みたい場合、ls(1)コマンドの出力結果をgrep(1)に流し込み、「grep ^d」のように指定して実行すればよい。行頭や行末で絞り込むことができるケースは結構多いので、まずこの指定方法は覚えておきたい。
今回覚えておいてほしいのはgrep(1)、-v、「^」、「$」だ。これらを組み合わせるだけでもさまざまなフィルタリングが可能になる。ぜひ試してみていただきたい。