トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

Linux:awkで標準出力をファイルにリダイレクトするときのハマりどころ

Last-modified: 2013-11-25 (月) 23:52:27 (3135d)
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