AWK
テンプレート:プログラミング言語 AWK(オーク)は、UNIX 上で開発されたプログラミング言語で、CSVファイルなどの文字ファイルの処理に用いられる。
概要
AWK は、ベル研究所における UNIX 開発の過程で、sed や grep のようなテキスト処理ツールに演算機能を持たせた拡張ツールとして開発された。
AWK は、簡単なスクリプトを記述することで、効率的にテキストファイルを処理することを目的として開発された。当初はそれほど多くの機能は無かったが、普及するにつれ、さまざまな処理を AWK で実行したいと考えるユーザーが増え、その希望に応えて機能の拡張が行われた。その結果、汎用のプログラミング言語と比べても遜色が無いほどの機能を持つようになり、テキスト処理だけに留まらず、開発者も予想しなかったような大規模なプログラミングに使われるような例もあらわれた。一方、本来のテキスト処理用ツールとしても扱いやすく、現在でも CSV や TSV 形式のファイルを簡易に処理するなどの目的で広く使用されている。
名称の AWK は、開発者であるアルフレッド・エイホ、ペーター・ワインバーガ、ブライアン・カーニハンの3人の苗字の頭文字を取って付けられたものであるが、AWK は「オーク」と読み、「エー・ダブリュー・ケー」と読んではならないと著者らはしている[1]。また、全て小文字で awk
とした場合、UNIX ないし Plan9 における、AWK のインタプリタ処理系プログラム自体(他の多くのコマンドと同じく全て小文字である)を指してそうしていることがある。
AWK の文法
基本構成
AWKのスクリプトは、パターンとアクションの組を並べた形になっている。実行を開始すると、まず BEGIN
パターンのアクションを実行する。以降、入力を読み込んでは、レコードセパレータ(デフォルトでは行末)までを1レコードとし、フィールドセパレータに従ってフィールドに分割してから、レコードがパターンにマッチするかを調べ、パターンにマッチしたらそのパターンに対応するアクションを実行する。一致するパターンが複数ある時は、該当するアクションが上から順に全て実行される。これを入力が尽きるまで繰り返す。入力が尽きたら、END
パターンのアクションを実行し、終了する。
データ型には、数値(全て倍精度浮動小数点型で扱われる)と文字列と連想配列がある。ただし、連想配列にできるのは変数のみで、連想配列の中身(要素)は連想配列にできない、と少々変則的だが、この制限によりループするようなデータ構造を作ることができなくなっており、仕様と実装を単純化している。連想配列のインデックスに数値を使うと、数値を表現する文字列に変換されて扱われる(たとえば foo[11] は foo["11"] と同じ)。この仕様により、効率はともかく通常の配列のように使うこともできる。
スクリプトの基本構成は次のようになる。
BEGIN {
(開始処理)
}
(パターン 1) {
(アクション 1)
}
(パターン 2) {
(アクション 2)
}
...
END {
(終了処理)
}
BEGIN
、END
アクションは必須ではない。
例として、テキストファイル内の全ての行のうち、「#anpi
」「#hinan
」「#jishin
」という文字列を含む行の数をカウントするプログラムを以下に示す。
BEGIN {
anpi = 0
hinan = 0
jishin = 0
}
/#anpi/ {
++anpi
}
/#hinan/ {
++hinan
}
/#jishin/ {
++jishin
}
END {
print "「#anpi」という文字列を含む行の数は " anpi " 行です。"
print "「#hinan」という文字列を含む行の数は " hinan " 行です。"
print "「#jishin」という文字列を含む行の数は " jishin " 行です。"
}
なお、AWK では、まだ代入されていない変数は暗黙のうちに 0
または ""
で初期化されると仮定してよいので、上の例での BEGIN ブロックは必須ではない。
パターンには以下のように開始と終了を定義するパターンもある。
/開始パターン/,/終了パターン/ {
アクション
}
例えば、以下のように定義すると、"Hello"
を含む行から、"Bye"
を含む行まで(その行を含む)の間、アクションが実行されその行が出力される。
/Hello/,/Bye/ {
print $0;
}
変数
AWK の特徴の一つとして変数が型を持たないことが挙げられる。変数宣言が不要で、プログラム中で使用される変数は暗黙のうちに初期化される。このため、未定義変数や未初期化変数を参照することによるエラーは AWK には存在しない。
AWK は算術演算のような数値を必要とする文脈では暗黙に値を数値に変換し、逆に文字列を必要とする場合には文字列に変換する。例えば、
a = "01"
b = 2
c = "a"
d = a + b
e = a + b + c
のような例では、d
および e
の値は 3
になる。
こうした暗黙の変換は便利であると同時に、ユーザの意図しない結果を生むこともある。
また、変数に入っているのがどちらかわからないが、必ず数値が必要という場合などに
x + 0
のように0を足したり、逆に必ず文字列が必要という場合などに
x ""
のように""を結合させたり、という常套手段がある。
関数
AWK では、関数を定義して使用することが可能である。
関数の定義は次のようになる。
function 関数名 (引数1, 引数2, …)
{
命令文1
命令文2
:
}
AWK の変数は、引数を除いて全て大域変数であり、局所のスコープを持つのは引数として宣言された変数だけである。このため、テクニックとして、関数定義で余分な引数を宣言し、それを局所変数として使う、ということがおこなわれる。AWK では、関数の呼び出し時に、実引数の個数が仮引数の個数より少なくても、省略とみなしエラーとしない。これを利用して、余分な引数を局所変数として使うのである。
function 関数名 (引数1, 引数2, 引数3, 局所変数1, 局所変数2, …)
{
…
}
このように関数を定義して、この関数を呼び出すときに引数を3つしか使わなければ、局所変数1 以降は局所変数として扱える。構文上の区別は無いが、判読性を向上させるために両者の間に十分な空白を挿入するのが慣例になっている。
function 関数名 (引数1, 引数2, 引数3, 局所変数1, 局所変数2, …)
また、AWK の関数は再帰呼び出しもできる。
制御構造
AWK の制御構造には以下のようなものがある。
if
(
式)
文真if
(
式)
文真else
文偽for
(
式初期化;
式条件;
式更新) 文for
(
変数in
配列)
文while
(
式)
文真do
文真while
(
式)
break
continue
next
(以降の文の実行および以降のパターン処理をせずに、次のレコードの処理を開始する)nextfile
(現在の入力ファイルの残りを読み込まずに、次のファイルの処理を開始する)return
(関数の処理を停止し、関数の呼び出し元に制御を戻す。値が指定されてあれば値を返す。)exit
(プログラムの実行を終了させる)
また、制御構造の他に、以下の文がある。
{
文1;
文2;
…;
文N}
print
printf
delete
(連想配列の全部ないし要素を削除)
AWK の処理系
もともとのAWKは、UNIXに付属していたものであったが、様々なプラットフォームに移植された他、GNU AWK(gawk
)を代表に、他の実装も多い。
- 旧版
- 1970年代後半から1980年頃開発されていたもので、V7の頃のUNIXに付属、『UNIXプログラミング環境』(en:The Unix Programming Environment)§4.4での説明で使われている版でもある[2]。関数のユーザー定義ができないのが、現在と比べると大きな制限である。これ、ないし次を指して、日本ではくだけた感じで「元祖」などとも。
nawk
- 1980年代後半頃までのバージョンアップにより登場したもので、SVR3の頃のUNIXに付属[3]。旧バージョンと区別してnawk(new awk)とも。関数のユーザー定義などの機能が追加された。一つの真正の、といった感じで、他と区別する場合は one true awk などとも呼ばれる。(BSDでは本家 UNIX とは別の実装になっているtoolも多いが)FreeBSD(バージョン5およびそれ以降)の
/usr/bin/awk
などはこれである。大きな機能追加などは以前から無いが、現在もメンテナンスされている。 gawk
- GNU プロジェクトによる AWK の実装。GNU/Linux ディストリビューションでは
awk
という名前でもこちらのことが多い。POSIX 1003.2 コマンド言語とユーティリティ規約に定められた言語の定義に適合している。マルチバイト文字への対応やネットワークへの接続機能など、オリジナルのawk
には無い多数の拡張が加えられており、現在もバージョンアップが続いている。 jgawk
gawk
がマルチバイト文字に対応する以前に作られたgawk
の日本語文字対応拡張版。mawk
- マイク・ブレナン[4]による AWK の実装。オリジナルの
awk
に少数の拡張が加えられている。 mawk
MBCS- 木村浩一[5]による
mawk
のマルチバイト拡張。 a2p
- AWK スクリプトを Perl スクリプトに変換するトランスレータ。Perl 配布キットに含まれている。
- 標準
- POSIXで標準化されている( http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html )。
脚注
参考文献
- プログラミング言語AWK
- テンプレート:Cite book - 「AWK book」(AWK 本)などと呼ばれ、C言語におけるK&Rのような扱いの本である。日本版は版元の出版事業撤退により最初に絶版となる。
- テンプレート:Cite book - トッパン 1989年刊の再刊。
- テンプレート:Cite book - 新紀元社から復刊されたものの、3度目の絶版となる。
- テンプレート:Cite book - ユニバーサル・シェル・プログラミング研究所から3度目の復刊がなされた。
- テンプレート:Cite book - アスキーの256本のひとつで、通称「AWK256本」とも呼ばれており、現在も販売中のベストセラーである。
- テンプレート:Cite book
- テンプレート:Cite book
関連項目
外部リンク
- Effective AWK Programming - A User's Guide for GNU Awk の日本語訳
- AWK のまとめ — 弘前大学 教育学部 教育実践研究指導センター 小山智史
- aaa - the Amazing Awk Assembler by Henry Spencer(英語)
- テンプレート:Man
- ↑ たとえばカーニハンによる『プログラミング言語AWK』の日本語版序文に見られる。なお、同著の表紙にはオオウミガラス(テンプレート:Lang-en-short)が描かれており、これもその主張の強調である。
- ↑ 『AWKを256倍使うための本』 p. 49
- ↑ 『AWKを256倍使うための本』 p. 49
- ↑ テンプレート:Lang-en-short
- ↑ ハンドル名 Bruce