熊沢です。
y_shiro@xxxxxxxxxxxxxxxxさんの<20041130113007.55428a5d.y_shiro@xxxxxxxxxxxxxxxx>から
> しかし、
> $ grep X-Mailer * > x-mailer.txt
> $ grep X-Mailer * > x-mailer.txt
> とした場合にだけ、なぜひたすら『読んで、書いて』といった状態になるのでしょうか?
話を簡単にしてみます。
ファイルとして a b cがあり、
grep test * > c
とします。aにはtestを含む行が3行あり、bには1行あります。cには何もあり
ません。
また、grepの出力はバッファリングされず、grep が出力したものはすぐにcに
出力されるものとします。 ← ここが肝です。
aの中身としては例えば以下のようなものとします。
test a-1
test a-2
test a-3
grep test * > cは展開すると grep a b c > cとなります。
動きを考えると、
1) grep が起動した時点でcの大きさは0となる
2) 最初にaの中を検索し、3行出力する
その時点でのcの中身の例
a:test a-1
a:test a-2
a:test a-3
3) 次にbの中を検索し、1行出力する
その時点でのcの中身
a:test a-1
a:test a-2
a:test a-3
b:test b-1
4) 次にcの中を検索すると
まず、a:test a-1があるのでそれを出力する。その結果、cの内容が
a:test a-1 ← grepはここまで検索
a:test a-2
a:test a-3
b:test b-1
c:a:test a1
となる。更に読んで出力していくとcの中身は
a:test a-1
a:test a-2
a:test a-3
b:test b-1 ← grepはここまで検索
c:a:test a-1
c:a:test a-2
c:a:test a-3
c:b:test b-1
と順次増えて行く。更にcの内容を検索していくと
a:test a-1
a:test a-2
a:test a-3
b:test b-1
c:a:test a-1 ← grepはここまで検索
c:a:test a-2
c:a:test a-3
c:b:test b-1
c:c:a:test a-1
と更に増えていく。
といった形になります。
実際にはgrepの出力がバッファリングされているためパターンマッチした行を
出力してもリダイレクト先のファイルに直ぐに書き込まれず、メモリ内に一時
的には留まることになります。出力量が増えてきてバッファが溢れるか、ファ
イルをクローズした時点で最終的にファイルに反映されます。
aやbのマッチングした行が小さければバッファリングされた結果としてcに直
ぐに反映されないため、サイズ0のcのファイルを読んで終了するか、
cのファイルをマッチングしたものを(cに)出力してもそれがcに反映されない
ため直ぐにファイルの終端となって終わります。
aやbが十分以上に大きい場合、パターンマッチングした結果は(バッファのオ
ーバフローを経て)cに直ぐに反映されていきます(上記のような流れになって
いく)。そこで、cに出力した行にマッチングしてcに出力し、それを更に読ん
でマッチングした結果をcに出力し、... 以下繰り返し ... という動きになり
ます。
では。
--
Kazuya Kumazawa