シェルプログラミングTips

readとパイプの使い分け

シェルは標準入力からデータを読み込むための組み込みコマンドreadを提供している。readを利用すると標準入力からのデータを任意の変数に代入することができる。この機能を利用すると特定の行のみを取り出すといった処理をawk(1)やcut(1)を使わずともシェルスクリプトのみで記述できるようになる。

たとえば3列目のデータのみを取り出す処理は次のようなシェルスクリプトで処理できる(self-read.sh)。

#!/bin/sh

seq 100000              |
paste - - - - -         |
while read a b c d e
do
echo $c
done

awk(1)を使うのであれば、この処理は次のようになる(self-awk.sh)。

#!/bin/sh

seq 100000              |
paste - - - - -         |
awk '{print $3}'

readは便利な組み込みコマンドだが、大量のデータを処理する場合には性能が期待できないという特性も持っている。次のように実行時間を比較すると性能差が明らかになる。

$ /usr/bin/time ./self-read.sh > /dev/null
0.17 real         0.13 user         0.08 sys
$
$ /usr/bin/time ./self-awk.sh > /dev/null
0.02 real         0.06 user         0.00 sys
$

逆に、処理するデータが少ない場合にはプロセスをfork()させる必要がないreadの方が処理が高速になる。数行程度の処理であればreadを、大量のデータならパイプで接続して別のコマンドで処理を実行するようにすれば良い。

パイプで接続してほかのコマンドで処理する方法はマルチコア/プロセッサを効率よく利用することにもなるため、コア/プロセッサが多数ある環境ではパイプにより処理の並列化がより効果的となる。

last modified: 2014-01-13 16:01:13