02 月 09 日(木)

フィルタ言語 AWK (4)

AWK をより効率的に記述し,より高度に活用しよう.

AWK の第一歩 gawk 日本語マニュアル 等を参考にしながら, 作業を進めて行こう.


AWK の入出力

これまでは,入出力として, コマンドラインに指定されたデータファイルからの入力と 標準出力への出力しか利用してこなかった. しかし,AWK の入出力機能はこれらだけに限られている訳ではない. シェルやC言語と同様に, ファイル・標準入出力・コマンドとの間の入出力機能を備えている:

詳しくは, マニュアルの“入出力ステートメント”の項目 を参照せよ.


AWK のユーザ関数

次の形式で,AWK でも関数を定義できる:

function 関数名(引数1, 引数2, ...) {
	アクション
}

シェルやC言語に似ているが, 共通点・相違点に注意しよう:

ユーザ関数は,単純なスクリプトではあまり使われないが, 複雑なスクリプトではコンパクト化のために重宝.

詳しくは, AWK オンラインマニュアルの“関数”の項目 を参照せよ.


AWK の組み込み関数

AWK には,C言語のライブラリ関数のような組み込み関数もある. 詳しくは, AWK オンラインマニュアルの“数値関数”,“文字列関数”, および“時間関数”の項目 を参照せよ.

簡単な例として,sed のような AWK スクリプト sed.awk を作成してみよう:

#!/usr/bin/awk -f
# 説明:sed のような AWK スクリプト
# 使い方:sed.awk r='正規表現' s='置換文字列' ファイル名 ...

{
	sub(r, s, $0)		# レコード $0 中の正規表現 r を 文字列 s に置換
	print $0
}

このスクリプトの使用例は次の通り:

$  ./sed.awk  r='#.*'  s=''  sed.awk

これは,次のコマンドと同じ結果となるハズ:

$  sed  's/#.*//'  sed.awk

ちなみに,この例では, スクリプトからコメント(各行の # 以降の文字列)を除去している.

なお,sed については, 以前のページsed オンラインマニュアル を参照せよ.

次の例では,sed.awk を改造し,ユーザ関数を定義してみた:

#!/usr/bin/awk -f
# 説明:sed のような AWK スクリプト
# 使い方:sed.awk r='正規表現' s='置換文字列' ファイル名 ...

function sed(reg, str) {
	sub(reg, str, $0);
	print $0;
}

{
	sed(r, s);
}

なお,この例では,関数化によってスクリプトがかえって長くなってしまったが, 何をするスクリプトなのか一目瞭然(いちもくりょうぜん)になった.


本日の課題

今回の課題については,任意提出とする. 未提出でも減点とはしないが, 特に,成績を挽回したい者は取り組むこと.

上に紹介した sed.awk では,コマンドラインの記述がちょっと面倒臭い. 本来の sed に近いコマンドライン形式となるように改良せよ.

レポートには,スクリプトとデータだけでなく, どのように改良したのかも説明すること.

アドバイス:

レポート提出 注意事項

(c) 2017, yanagawa@kushiro-ct.ac.jp