AWK

出典: フリー百科事典『ウィキペディア(Wikipedia)』
Awkから転送)
ナビゲーションに移動 検索に移動
AWK
パラダイム スクリプト言語 ウィキデータを編集
登場時期
  • 1979 ウィキデータを編集
開発者 アルフレッド・エイホ ウィキデータを編集
最新リリース IEEE Std 1003.1-2008 /
影響を受けた言語 SNOBOL ウィキデータを編集
テンプレートを表示

AWKオーク)は、プログラミング言語の一つ。 テキストファイル、特に空白類(スペースの他、タブなど)やカンマなどで区切られたデータファイルの処理を念頭に置いた仕様となっているが、 一般的なプログラミングに用いることも可能である。 UNIX上で開発された。

概要[編集]

AWKは、ベル研究所におけるUNIX開発の過程で、 sedgrepのようなテキスト処理ツールに演算機能を持たせた拡張ツールとして開発された。

簡単なスクリプトを記述することで効率的にテキストファイルを処理することを目的であった。 当初はそれほど多くの機能は無かったが、 普及するにつれ、さまざまな処理をAWKで実行したいと考えるユーザーが増え、 その希望に応えて機能の拡張が行われた。 その結果、汎用のプログラミング言語と比べても遜色が無いほどの機能を持つようになり、 テキスト処理だけに留まらず、開発者も予想しなかったような大規模なプログラミングに使われるような例もあらわれた。 一方、本来のテキスト処理用ツールとしても扱いやすく、 現在でもCSV形式のファイルを簡易に処理する、などの目的で広く使用されている。

「AWK」という名称は、開発者であるアルフレッド・エイホピーター・ワインバーガーブライアン・カーニハンの3人の苗字の頭文字を取って付けられたものであるが、 AWKは「オーク」と読み、「エー・ダブリュー・ケー」と読んではならないと著者らはしている[1]。 また、全て小文字でawkとした場合、 Unix系OSないしPlan9における、AWKのインタプリタ処理系プログラム自体(他の多くのコマンドと同じく全て小文字である)を指してそうしていることがある。

AWKの文法[編集]

基本構成[編集]

AWKのスクリプトは、パターンとアクションの組を並べた形になっている。 実行を開始すると、まずBEGINパターンのアクションを実行する。 以降、入力を読み込んでは、 レコード分離文字(既定では改行)までを1レコードとし、 ユニット分離文字(既定では連続するスペースまたは水平タブ)に従ってフィールドに分割してから、 レコードがパターンにマッチするかを調べ、パターンにマッチしたらそのパターンに対応するアクションを実行する。 一致するパターンが複数ある時は、該当するアクションが上から順に全て実行される。 これを入力が尽きるまで繰り返す。 入力が尽きたら、ENDパターンのアクションを実行し、終了する。 すなわち、テキストストリームをシーケンシャルに読み込み、入力されるテキストストリームをレコードセパレータ毎に区切り、1行毎にスクリプトに記述されたアクションを順次実行する。

ファーストクラスデータ型は、数値(全て倍精度浮動小数点型で扱われる)と文字列である。

他に文字列をキーとした連想配列があるが、 連想配列はファーストクラスではなく関数の返戻値にできないなどデータというよりは、配列変数という変種の変数があるといったような扱いである。 連想配列の中身(要素)を連想配列にすることはできないため、ループするようなデータ構造を作ることは不可能。 連想配列のキーに数値を使うと、文字列に変換したものがキーとなる。 arr[x, y]のようにして多次元配列のように見えるアクセスもできるが、 実際には各次元を必要であればまず文字列化した後に、グローバル変数SUBSEPの文字列(デフォルトではU+001C <control-001C>)をセパレータとして連結した文字列をキーとしてアクセスする。

スクリプトの基本構成は次のようになる。

BEGIN {
    開始時処理
}
パターン1 {
    アクション1
}
パターン2 {
    アクション2
}
……
# コメント
END {
    終了時処理
}

BEGINENDアクションは必須ではない。

例として、テキストファイル内の全ての行のうち、 空行の数と「林檎」・「りんご」または「リンゴ」という文字列を含む行の数をそれぞれ出力するAWKプログラムを示す。

BEGIN {
    # 行の個数を表わす変数を宣言・初期化
	blank_line = 0
	bol_apple = 0
}

/^$/ {
	++blank_line
}

/(林檎|りんご|リンゴ)/ {
	++bol_apple
}

END {
	print "空行は" blank_line "行です。"
	print "「林檎」・「りんご」または「リンゴ」という文字列を含むのは" bol_apple "行です。"
}

なお、AWKでは、まだ代入されていない変数は暗黙のうちに0または""で初期化されると仮定してよいので、上の例でのBEGINブロックは必須ではない。

パターンには以下のように開始と終了を定義するパターンもある。

/開始パターン/,/終了パターン/ {
    アクション
}

例えば、以下のようなプログラムは, 「<script>」を含む行から「</script>」を含む行まで(その行自身を含む)の間、指定されたアクションが実行する(この場合は単に行全体を出力する)。

/<script>/,/<\/script>/ {
    print $0;
}

変数[編集]

AWKの特徴の一つとして変数が型を持たないことが挙げられる。 変数宣言が不要で、プログラム中で使用される変数は暗黙のうちに初期化される。 このため、未定義変数や未初期化変数を参照することによるエラーはAWKには存在しない。

AWKは算術演算のような数値を必要とする文脈では暗黙に値を数値に変換し、逆に文字列を必要とする場合には文字列に変換する。 例えば,

a = "01"
b = 2
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の制御構造には以下のようなものがある。

if文
  • if () 式が真の時に実行される文
  • if () 式が真の時に実行される文 else 式が偽の時に実行される文
for/while文
  • 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に付属[2]。旧バージョンと区別して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
マイク・ブレナン(: Mike Brennan)作。旧版のawkに少数の拡張が加えられている。バイトコードに変換されて実行されるため,高速な動作が期待できる。またgawkよりもバイナリサイズが小さい。
mawk MBCS
木村浩一(ハンドル名:Bruce)によるmawkのマルチバイト拡張。
標準
AWKはawk(1)としてIEEE Std 1003.1-2017で標準化されている[3]
また,Linux Standard Baseでも指定コマンドになっている[4]

脚注[編集]

  1. ^ たとえばカーニハンによる『プログラミング言語AWK』の日本語版序文に見られる。なお、同書の表紙にはオオウミガラス: great auk)が描かれており、これもその主張の強調である。
  2. ^ a b 志村 拓、1993、『AWKを256倍使うための本』、アスキー・メディアワークス ISBN 4-7561-0162-3
  3. ^ awk”. IEEE 及び The Open Group (2013年). 2018年10月14日閲覧。
  4. ^ Relevant Commands”. Linux Foundation (2015年). 2018年10月14日閲覧。

参考文献[編集]

関連項目[編集]

外部リンク[編集]