標準入力を2箇所以上に同時出力したい


一時ファイルを作りたくない

例えばこんなデータがhogeコマンドから出力されるとして、

# comment line 1
# comment line 2
code line 1
code line 2
# comment line 3
code line 3

これを2つのコマンドに入力したい場合、

一時ファイルを使う
$ hoge > source.txt
$ grep -v \# source.txt > code.txt
$ grep \# source.txt > comment.txt

のように一時ファイルを作ればいいのだが、こんなことをせず2箇所に直接hogeの出力を渡したくなった。
出力の分岐といえばteeコマンド。本来の出力先はファイルだが、これをストリームに出力するようにしてあげよう。

名前付きパイプ

名前付きパイプでcode.txtcomment.txtを同時に得る方法。

名前付きパイプを使う
$ mkfifo named-pipe
$ (grep -v \# < named-pipe > code.txt) &
$ hoge | tee named-pipe | grep \# > comment.txt

プロセス置換

プロセス置換を使う方法。名前付きパイプを使わなくてもいいなら簡素に書けていい感じ。

プロセス置換を使う
$ hoge | tee >(grep -v \# > code.txt) | grep \# > comment.txt

もっと同時出力する

teeは複数のファイルに出力できるので3箇所以上に流すこともできる。

名前付きパイプで
$ mkfifo named-pipe1 named-pipe2
$ (grep -v \# < named-pipe1 > code.txt) &
$ (grep \# < named-pipe1 > comment.txt) &
$ hoge | tee named-pipe1 named-pipe2 > source.txt
プロセス置換で
$ hoge | tee >(grep -v \# > code.txt) >(grep \# > comment.txt) > source.txt

便利〜