Linux:awkで標準出力をファイルにリダイレクトするときのハマりどころ
Last-modified: 2013-11-25 (月) 23:52:27 (3659d)
Top / Linux:awkで標準出力をファイルにリダイレクトするときのハマりどころ
Linux:awkで標準出力をファイルにリダイレクトするときのハマりどころ †
awkで標準出力をファイルにリダイレクトしたいときにハマったので記録として残します。
これの結果をファイルに出力したいです。
sar -p 1 1000 | awk '/all/ { ct = strftime("%Y%m%d%H%M%S");print ct,$3}'
ダメなやり方 †
これでは出ませんw
sar -p 1 1000 | awk '/all/ { ct = strftime("%Y%m%d%H%M%S");print ct,$3}' > output.txt
なぜかというと、awkが出力をバッファリングして、途中でctrl+cをおすと、バッファに出力した内容が消えてしまうからです。
参考
正解 †
上の参考URLにちゃんと書いてありますw
Controlling Output Buffering with system
関数fflushはファイルやパイプに対する出力のバッファリングを 陽に制御する機能を提供する。しかしこれは、他のawk処理系では 使えないのでこれを使うと可搬性(portability)に欠けることになる。 出力バッファをフラッシュするための手段として、system関数を 空文字列を引数にして呼び出すというものがある。
system("") # 出力をフラッシュする
gawkはこのようなsystem関数の使い方を特殊なものとして みなし、シェル(あるいは他のコマンドインタープリター)を何のコマンドも なしに起動するようなことはしない。このため、gawkでは この使い方は便利であるばかりでなく、効率も良い。 このやり方は他のawk処理系でも使えることが多いので、 必要ないシェルを起動してしまうことを避ける必要もない (他の処理系では、標準出力のバッファだけがフラッシュされ、その他の 出力バッファはフラッシュされないかもしれない)。
なるほど、つまり、こんな感じです。
sar -p 1 1000 | awk '/all/ { ct = strftime("%Y%m%d%H%M%S");print ct,$3}{system("")}' > output.txt
もちろん、teeでも出力できますw
sar -p 1 1000 | awk '/all/ { ct = strftime("%Y%m%d%H%M%S");print ct,$3}{system("")}' | tee output.txt
まあ、ちゃんとリファレンス読めばできるってことですなw