パイプライン処理

Unixの便利な機能として、 一つのプログラムの標準出力をそのまま他のプログラムの標準入力に 送るためのしくみが用意されている。

たとえば、フィルター型のプログラム (データを標準入力から読み、標準出力に書き、 他の読み書きは原則としてしないもの) prog1, prog2 があったとする。 prog1の標準出力を、いったんあるファイルにとり、それをprog2に読ませる ことは次のような手順でできる。

% prog1 > tmpfile
% prog2 < tmpfile
% rm tmpfile
(中間結果を入れるファイル名は何でもよいが、 一時的にだけ必要なファイルなのでtemporary fileの略でこの名前にした。)

しかし、中間段階のファイルの内容を確認しなくてよいのならば、 これを、

% prog1 | prog2
のような形で実行することができる。2つのプログラムを、縦棒(|)でつなぐ。 このような処理を、パイプライン処理という。
% prog1 | prog2 | prog3 | prog4 | prog5 
のように、たくさんつなぐこともできる。

たとえば、今注目しているディレクトリ(loginしてcdをしていなければ 自分のホームディレクトリ)のファイルの詳しい一覧表を出すことは

% ls -l
で可能である(オプションの文字は、マイナス、エル)。しかし、ファイルの数 が多いと、文字が流れて(スクロールして)全部が見えない。一方、テキスト ファイルを画面におさまる行数ごとに止めて表示するコマンドとしてlessが ある。ls -lの出力するものはテキストファイルとみなせるから、
% ls -l | less
のようにすれば、ファイル一覧を画面を止めて見ることができる。 なお、lessは、ページをめくるための空白文字や、終了するための「q」 などをキーボードから受けとるが、これは標準入力とは別の機能を使って いるので、標準入力をパイプラインにしてもかまわないのである。

フィルター型のプログラムの例文で、 気温のデータkion.tokyoのうちから4月のものだけを選ぶプログラムをerabu、 長期平均からの偏差を計算するプログラムを hensa として あらかじめコンパイルしてあったとすれば (名前をa.outから変える方法は 別記事を参照)、 4月の気温の長期平均からの偏差を

% erabu < kion.tokyo | hensa > kion.4gatu.hensa
として、(たとえば)kion.4gatu.hensaというファイルに得ることができる。

catコマンドとの組み合わせ

catはUnixでテキストファイルの内容を表示するためのいちばん簡単なコマンド でもあるが、指定された複数のファイルの内容を結合して標準出力に出す機能がある。 このコマンドはパイプライン処理で能力を発揮する。

たとえば、 フィルター型プログラムの例 でとりあげた問題の中に、平均値からの偏差を計算する仕事がある。 例文 hensa.{p,f,c}のように、平均値と偏差を同じプログラムで計算するとすれば、 配列をとって入力データを読みこんでおく必要がある。 一方、平均値を別のプログラム heikin.{p,f,c}であらかじめ計算しておき、 偏差を計算するプログラムは、これの出力ともとの時系列データの両方を読み こんで動作するような設計も考えられる。そうすれば配列を用意する 必要はない。このとき、

というのがふつうの発想だが、 という約束にしておけば、 偏差を計算するプログラムは、標準入出力だけを使ったフィルター型 にすることができる。このようにした例が、 hensa2.p, hensa2.f, hensa2.c に用意してある。

このプログラムを使うには、次のようにすればよい。 ただし、heikin、hensa2は、それぞれheikin.{p,f,c}、hensa2.{p,f,c}をコンパイル した機械語プログラムであるとする(名前のつけかえは 別記事を参照)。 kion は入力となる時系列データファイルの名前の一例、 kion.heikin, kion.hensaは処理結果につけたファイル名である。 catの出力がhensa2の入力になるパイプライン処理に注意してほしい。

% heikin < kion > kion.heikin
% cat kion.heikin kion | hensa2 > kion.hensa
さらに、catコマンドはファイル名のところに - を書くと標準入力を読むので、 heikinからパイプラインを続けて
% heikin < kion | cat - kion | hensa2 > kion.hensa
としてもよい。


1996-05-11; 2000-06-28; 2002-07-11
増田 耕一 (MASUDA Kooiti)

[目次へ]