色々と便利な awk(1) のちょっとした小技を紹介してみます。
system() を利用する際の注意
awk(1) の中で外部コマンドを実行する場合は組み込み関数 system() が利用できますが、この関数を利用して外部コマンドを実行すると入出力 stream がオープンされるので、ファイルディスクリプタが消費されてしまいます。
ですので awk(1) 内で何度も system() を実行すると、オープンできるディスクリプタの上限を超過してしまい、 awk(1) の実行が中断されてしまう可能性があります。
ですので、 close() を利用して system() がオープンした stream を閉じれば良いのですが、 awk(1) の system() では stream を明示的に扱いません。その様な場合は system() で実行したコマンドを close() の引数で指定する事で stream を閉じる事ができます。
awk '{
:
# コマンドを生成
command = sprintf("%s %s %s", command, arg1, arg2);
# コマンドを実行して結果を取得
buf = system(command);
# stream をclose
close(command);
:
}'
関数内ローカルな変数の使用
nawk(1) は function を利用する事で内部関数を作成する事ができますが、関数内でローカルな変数を明示的に定義する事ができません。
ところが関数宣言の仮引数部に変数を定義する事で、関数内ローカルの変数として利用できます。
awk '{
:
# 関数 foo の定義
# num: ループ数
# 以下ローカル変数
# i: ループウンタ
function foo(num, i)
{
# i はローカル変数扱いなので呼出元の i は影響を受けない
for(i=0; i<1num; i++)
:
}
:
foo(num);
:
}'
但し関数呼び出し時と関数定義時に引数の数が等しくないので、後に混乱しないためにコメントで明記するなどの処置は必要でしょう。