The AWK~plus Language Specification

AWK~plus

AWK の彼方に (Over The AWK)

The AWK~plus Programming Language は、
  • プログラム言語AWK (The AWK Programming Language) 仕様と GNU GAWK の主要な拡張機能の実装
  • 型推論と 関数型プログラミングによるシンプルな外観
  • 言語レベルでの ロックフリーでスレッドセーフな並列プログラミングのサポート
  • 動的型付 (インタプリタ) と 静的型付け (コンパイラ) をハイブリッドでサポートする型システム
などの特徴を持つ 次世代スクリプト実行環境です。

AWK プログラム (Program)

AWK プログラム (スクリプト) は パターンとアクションおよびオプションの関数定義からなる。

package パッケージ指定 (* Compilerで有効 *)
import (* Nonimplement *)
extends 継承クラス指定 (* Compilerで有効、The Scala形式で指定 *)
var グローバル変数定義
val グローバル変数定義
パターン { アクション }
function 関数定義

パターン (Pattern)

パターンは以下のとおり。

BEGIN (* 他のパターンとの組み合わせは不可 *)
END (* 他のパターンとの組み合わせは不可 *)
Expression
/正規表現/
パターン && パターン
パターン || パターン
! パターン
( パターン )
パターン , パターン (* 他のパターンとの組み合わせは不可 *)
空のパターン

アクション (Action)

アクションは以下のとおり。

var ローカル変数定義
val ローカル変数定義
function ローカル関数定義
break
continue
delete Array[ '[' Expression ']' ]
do Statement while ( Expression )
exit [ Expression ]
(* 式の値が 0以外の場合は System.exit() で shellへの復帰値を設定する (JavaVM を終了) 制御の流れを変更する目的で使用する場合(BEGINからENDへの遷移など)は exit 0 ('0' の場合は exit を発行しない) の利用を推奨 *)
Expression
if ( Expression ) Statement [ else Statement ]
入出力文
for ( Expression; Expression; Expression ) Statement
for (変数 in Arr) Statement (* Arr は 配列 または イテレータ *)
next
nextfile
new クラス名 [ : タ イプ ] [ パラメータ ]
return [ Expression ]
throw インスタンス
try Statement
  { catch 変数名 : クラス名 Statement }
  [ catch [ 変数名 ] Statement ] (* else の場合 *)
  [ finally Statement ]
while ( Expression ) Statement
{ Statements }
switch ( Expression ) { case Expression or パターン: Statement } [ default: Statement ]

コメント (Comments)

コメントは 一般敵に利用されている形式をサポートしており AWK と C スタイルのコメントを受け付ける。

# (* AWKスタイル行コメント *)
// (* C++スタイル行コメント *)
/* (* Cスタイルコメント *) */

数値 (Numbers)

数値は 数値区切り文字 ('_') を含む 下記の形式で指定する。

0 [Xx] [0-9A-Fa-f_] (* 16 進数 *)
0 [Bb] [01_] (* 2 進数 *)
([0-9][0-9_]*[.]?[0-9_]*|[.][0-9_])+([eE][+-]?[0-9_]+)?(* 10 進数 *)

文字列 (Strings)

文字列は 下記の形式をサポートしており 目的に応じたスタイルでの記述が可能である。

" (* 文字列リテラル *) "
' (* HTMLスタイル *) '
""" (* マルチライン文字列 *) """
/ (* 正規表現 *) /

Note:  マルチライン文字列は """ 以外の文字列を改行を含めてそのまま受け付ける。

Note:  正規表現を文字列として扱うことにより (本来は正規表現が有効でない場所での使用において) 直感適な記述が可能になった。

FS=/[ ]/;  # FSに正規表現"[ ]"を代入、GNU AWKでは FS=$0~/[ ]/; と解釈される

変数定義 (Variable declarations)

変数定義は以下のとおり。

val 変数名 [ : タイプ ] = Expression
(* 変更不可能な変数で オブジェクトまたは プリミティブを定義する。 タイプ指定は型推論により不要であり キャストが必要な場合に指定すればよい *)
var 変数名 [ : タイプ ] = Expression
(* 変更可能な変数で、 タイプ指定により効率的なコードを生成する *)

関数定義 (Function declarations)

関数定義の宣言の各要素は省略可能でタイプ指定が追加された。

関数定義 = 'function' 名前 ['(' { 仮引数 [':' タイプ] } ')' '(' { ローカル変数 [':' タイプ] } ')' ] [':' 戻り値タイプ] ( '{' 文 '}' | ';' ) ;

宣言要素を省略した場合の意味は以下のとおり。

関数定義 = 'function' 名前 '(' { 仮引数 } { ローカル変数 } ')' '{' 文 '}' (* AWK標準スタイル *)
          | 'function' 名前 '(' { 仮引数 } ')' '(' { ローカル変数 } ')' '{' 文 '}' (* ローカル変数を()で明示的に宣言 *)
          | 'function' 名前 '{' 文 '}' (* 仮引数とローカル変数宣言なし *)
          | 'function' 名前 ['(' { 仮引数 } ')'] ';' (* 関数プロトタイプ宣言 *)
          | 'function' '{' 文 '}' (* 無名関数 *)
          ;

関数呼び出し (Calls)

関数(メソド)呼び出しは以下のとおり。

関数呼び出し = 名前 ['(' Expression { ',' Expression } ')'] ;

Note:  関数呼び出しパラメータが空の場合の '()' は省略可能であり 関数呼び出しとプロパティ参照の区別はない。

Note:  パラメータを区切る ',' は ')(' で置き換え可能であり 関数型言語でのカリー化 (Currying) 記述が可能、 さらに '(' ')' は '{' '}'に置き換え可能。

fun(a, b); fun(a)(b)  # AWK仕様で'('の前に空白は記述不可 (* 文字列結合と競合 *)
 fun(a) {b}  # 独自構文に似せた呼び出しが可能

関数値 (Function value)

関数値は他の関数と同じように呼び出せる関数オブジェクトで、 apply メソドが呼び出されたときに実行される。

関数値 = '.' 関数呼び出し ;

function add(a, b) { return a + b }
 function calc(x: Function) { return x.apply } # 関数値呼び出し
 print calc(.add(1, 2)) # 3

組み込み変数 (Builtin variables)

組み込み変数は以下のとおりで GNU AWKの主要な拡張機能をサポートする。

ARGC
ARGV の要素数
ARGIND
配列 ARGV のインデックス (現在処理中のファイル名が格納されている要素を指す)
ARGV
コマンド行引数配列 (添字 1 より格納され AWK へのオプションは含まない)
ARGV[0] の内容は不定。 AWK(C言語インターフェイス) では実行プログラム名が格納されるが Java にはその概念はない
BINMODE
入出力においてバイナリモード を制御 (Cygwin における行末の改行 "\n", "\r\n" 対策に相当)
CONVFMT
数値から文字列への変換書式 (既定値は %.6g)
ENVIRON
起動時の環境変数のコピー配列
ERRNO
入出力例外の理由を表わす文字 列
FIELDWIDTHS
固定長レコードを入力するため の空白で区切られたフィールド長のリスト (ASCII コード依存)
FILENAME
現在の入力ファイル名
FNR
現在の入力ファイルから入力したレコード数
FS
入力フィールドセパレータで 正規表現文字列 を受け付ける (既定値は空白で 空白 と TAB にマッチする)
IGNORECASE
文字列比較と正規表現マッチングで英大小文字を区別 (既定値は 0 て英大小文字を区別する)
LINT
コマンドラインオプション "--lint" の有無をアプリで制御
NF
現在の入力レコードのフィールド数
NR
現在までに入力したレコード数の合計
OFMT
数値の出力書式 (既定値は %.6g)
OFS
出力フィールドセパレータ (既定値は空白)
ORS
出力レコードセパレータ (既定値はプラットフォーム 依存の改行 "\n", "\r" または "\r\n")
PROCINFO
主にプロセス関連の拡張機能 ("/dev/pid", "/dev/ppid"など) を制御するための配列
RLENGTH
match で正規表現にマッチした文字列の長さ
RS
入力レコードセパレータで "正規表現文字列" を受け付ける (既定値は改行)
RSTART
match で正規表現にマッチした文字列の開始位置
RT
RS にマッチし入力レコードセパレータとなった入力テキスト
SUBSEP
多次元配列の添字区切り文字 (既定値は '\034')
TEXTDOMAIN
GNU AWK 固有機能で国際化に使用

特殊ファイル名 (Special file name)

以下の 特殊ファイル名をファイル名として指定できる。

"/dev/stdin"
標準入力 (ファイル記述子 0)
"/dev/stdout"
標準出力 (ファイル記述子 1)
"/dev/stderr"
標準エラー出力 (ファイル記述子 2)
"/dev/null"
NULL (ビットバケツ bit bucket)
"/dev/fd/N"
ファイル記述子 N に結び付けられたファイル (/dev/stdin, /dev/stdout, /dev/stderr... の実体)
"/inet/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT [ /接続タイムアウト(秒) ] [ /#文字コードセット ]"
INET通信
  • TCP/IP サーバソケット通信:       "inet://tcp/LOCAL-PORT/0/0"
  • TCP/IP クライアントソケット通信: "inet://tcp/0/REMOTE-HOST/REMOTE-PORT"
  • UDP ローカルソケット通信:         "inet://udp/LOCAL-PORT/0/0"
  • UDP リモートソケット通信:          "inet://udp/0/REMOTE-HOST/REMOTE-PORT"
"jdbc:SUBPROTOCOL:SUBNAME [ ドライバパラメータ ... ] [ ;; SQL文 ]"
  • jdbc:                 この URL が JDBC URL であることを表すスキーム名
  • SUBPROTOCOL: サブプロトコル (ドライバを識別する文字列)
  • SUBNAME:   接続先のホスト、データベース名称およびドライバオプション
  • ;; SQL文:         接続時に実行する SQL文 (オプション)
"http:// URL [ #文字コードセット ]"
ユニフォームリソースロケータ (Uniform Resource Locator) つまり World Wide Web 上のリソースへのポインタを表す
"file:// URL [ #文字コードセット ]"
ローカルファイルを表すURL

入出力 (Input/Output)

入出力ステートメントと関数は以下のとおり。

close([ Expression ])
ファイル名を省略した場合は 開いているストリームを全て閉じる
close(file , how)
双方向パイプを閉じる
fflush([ file | "" ])
出力バッファをフラッシュする、 ファイル名が空白("") のときは全ての出力ファイルを、 ファイル名を省略した場合は標準出力および標準エラー出力をフラッシュする
getline [ var ] [ <, |& file ]
次のレコードを var (省略時は $0) に読む (リダイレクト指定は <, |, |&) (* この関数は 文または関数として振舞う *)
next
現在のレコードの処理を終了して次のレコードの処理を開始する
nextfile
現在の入力ファイルの処理を終了して次の入力ファイルを読む
print [ Expression ... ] [ > file ]
式の値 (省略時は $0 ) を出力する (リダイレクト指定は >, >>, |, |&)
出力文字列中の "\n" は ORS に変換して出力する (* この関数は 文または関数として振舞う *)
printf format [ , Expression ... ] [ > file ]
書式付き出力 (リダイレクト指定は >, >>, |, |&) (* この関数は 文または関数として振舞う *)
system(command [redirect])
コマンドを実行して終了ステータスを返す
リダイレクト (redirect) 指定は以下のとおり
  • 1>&2 標準出力を標準エラーに出力
  • 2>&1 標準エラーを標準出力に出力
  • >[>]file ファイルに出力

Note:  "|&" は双方向パイプで、 INET 通信で使用する。 (ex. "inet://..." |& getline)

Note:  AWKは、 ファイル名を明示して存在しないファイルから入力した場合にエラーとしない仕様であるが エラーとするように変更した。 (この機能が必要な場合は、 try catch を使用すればよい)

数値関数 (Numeric functions)

数値関数は以下のとおり。

abs(x)
x の絶対値
atan2(x,y)
x/y のアークタンジェント
cos(x)
x の余弦
exp(x)
自然対数の底 e の x 乗
int(x)
小数点以下を切り捨てた整数値  (他 に double, float, long もある)
log(x)
x の自然対数
sin(x)
x の正弦
sqrt(x)
x の正の平方根
rand()
0 以上 1 未満の浮動小数点数の擬似乱数を返す
srand([ x ])
x を種として乱数を生成、 x 省略時は直前の種を返す

文字列関数 (String-Manipulation functions)

文字列関数は以下のとおり。

asort(source [ , dest ])
source 配列の要素を IGNORECASE に基いて ソート。 dest (または source) に出力し要素数を返す (出力配列の添字は 1 からの連番)
asorti(source [ , dest ])
source 配列の添字を IGNORECASE に基いて ソート。 〃
index(in, find)
文字列 in の中で文字列 find が出てくる最初の位置を返す
length([ string ])
string 中の文字数 (配列を指定した場合は 要素数)
match(string, regexp)
正規表現 regexp にマッチする string の最左、最長の文字列位置を返す
match(string, regexp ,array)
array はマッチした string の部分文字列配列を取得するための拡張引数
split(string, array [ , fieldsep ])
string を fieldsep によって分割し分割された結果を array に格納し要素数を返す
sprintf(format [ , Expression ... ])
printf がその引数を渡されたときに出力するであろう文字列を返す
strtonum(string)
string を検査してその値を返す (string が'0'で始まる場合は 8進数値, '0x'もしくは'0X'で始まる場合は 16進数値)
sub(regexp, replacement [ , target ])
正規表現 regexp でターゲット文字列 target を replacement で置換し置換数を返す
置換文字列 replacement のなかの '&' は 適合文字列に置き換えられる。 また '\&' でアンパサンドそのものを生成する
置換文字列で '\n' (n は 1 から 9 の数字) を指定することにより 正規表現にマッチした n 番目を前方参照する
gsub(regexp, replacement [ , target ])
正規表現 regexp でターゲット文字列 target を replacement で一括置換し置換数を返す
gensub(regexp, replacement, how [ , target ])
正規表現 regexp でターゲット文字列 target を replacement で how に基いて置換し置換した文字列を返す
substr(string, start [ , length ])
文字列 string の start 番目の文字から始まる長さ length 文字の部分文字列を返す
tolower(string)
大文字をすべて小文字に変換した文字列を返す
toupper(string)
小文字をすべて大文字に変換した文字列を返す

ビット操作関数 (Bit-Manipulation functions)

ビット操作関数は以下のとおり。 (精 度は unsigned int 32bit)

and(x, y)
x AND y を返す
or(x, y)
x OR y を返す
xor(x, y)
x XOR y を返す
compl(x)
x の2の補数を返す
lshift(x, count)
x を count ビット左にシフトした値を返す
rshift(x, count)
x を count ビット右に0を充填してシフトした値を返す

時間関数 (Timestamp functions)

時間関数は以下のとおり。

systime()
基準時点 (1970-01-01 00:00:00 UTC,) からの経過秒数(タイムスタンプ)を返す
mktime(datespec)
日付時刻を表す文字列をタイムスタンプに変換して返す
java.text.DateFormat を実装。 引数は "2007/02/28 00:00:00" など
strftime([ format [ , timestamp ] ])
指定したタイムスタンプ (省略時は現在時刻) を日付時刻を表す文字列に変換して返す
java.text.SimpleDateFormat を実装。 format省略時は Java デフォルトスタイル

組み込みコマンド (Builtin Commands)

プラットフォーム非依存とするために以下の (system) コマンドを抱え込んでいる。

cat [オプション]... [ファイル]...
ファイルまたは標準入力を結合し、標準出力へ書き出す
-n 全ての行の出力に行番号を付加
-b 空でない行の出力に行番号を付加
-s 連続した空行を圧縮する
-T TAB文字を`^I'で表示
date [+'フォーマット']
現在時刻を有効なFORMATで表示する (Thu Sep 29 11:13:18 JST 2011 など)
+フォーマット指定は、java.text.SimpleDateFormat 参照
echo [オプション]... [文字列]
文字列を表示する
-n 文字列の最後で改行しない
-e 文字列中のエスケープ文字を有効にする
-E エスケープ文字を処理しない (-e の逆)
\a alert (BEL)
\b backspace
\f form feed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\uFEFF UNICODE
\xFF Hex decimal
\0777 Octal decimal
exit 終了値
コマンドの終了値を設定する
sleep 時間
指定した時間停止する (時間は秒単位で指定し少数点形式も可能)
sort [オプション]... [ファイル]...
文字列をソートする
-b 各行の比較の際に、行頭の空白を無視する
-d アルファベット、数字、空白以外を無視する
-f アルファベットの大文字と小文字を区別しない
-g 数値として比較する
-n 先頭の文字列 (空白が前置されていても良い) を数値文字列として比較する
-r 比較の結果を逆順にする
-tSEP 指定した文字をフィールド区切りとして使用する
-u 同一内容の行は1度しか表示しない
+POS1[-POS2] POS1 から POS2 (POS2 省略時は行末) までが ソートキーとなり、フィールド位置は 0 から始まる
-POS2 end it at POS2(default end of line)
-kPOS1[,POS2] ソートキーを指定する別法。 フィールドと文字位置は 1 から始まる

演算子 (Operators)

式は 以下の演算子を用いて結合してもよい。

代入 = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '^=' | '**='
| '<<=' (* 左シフト代入 *)
| '>>=' (* 符号なし右シフト代入 *)
| '`&=' (* ビットごとのAND代入 *)
| '`|=' (* ビットごとのOR代入 *)
| '`^=' (* ビットごとのXOR代入 *)
| '`~=' (* ビットごとの補数代入 *)

;
条件 = 論理式 '?' 式 ':' 式 ;
論理和 = '||' ;
論理積 = '&&' ;
存在確認 = 式 'in' 配列名 (* 配列要素の存在確認 *)
| 関数値 'in' オブジェクト (* メソド、プロパティの存在確認 *)
;
代入互換性 = 式 'is' クラス名 ; (* instanceof *)
照合 = 式 '~' 正規表現 (* 適合 *)
| 式 '!~' 正規表現 (* 非適合 *)
;
関係 = '<' | '<=' | '>' | '>=' | '!=' | '=='
| '!==' | '===' (* 参照等価 *)
;
連接 (* 文字列の結合、空の演算子 *)
和、差 = '+' | '-' ;
積、商、剰余 = '*' | '/' | '%' ;
単項和と差 = '+' | '-' ;
論理否定 = '!' ;
累乗 = '^' | '**' ;
インクリメント、デクリメント = '++' | '--' ;
関数値 = '.' 関数呼び出し ;
= '$' ;
グループ化 = '(' 式 ')' ;

正規表現 (Regular Expressions)

AWK 正規表現エスケープシーケンスとの非互換点について説明する。

\\
バックスラッシュ文字
\a
アラート文字 (BEL) 正規表現 /\a/ は有効、 文字列エスケープ "\a" は不可 ("\u0007" で指定する)
\b
単語境界を表すメタ文字で '[' 文字クラス ']' でのみ 後退文字(BS)としての意味を持つ
\cx
x に対応する制御文字
\e
エスケープ文字 (ESC)
\f
用紙送り文字 (FF)
\n
改行文字 (LF)
\r
復帰文字 (CR)
\t
タブ文字 (TAB)
\v
垂直タブ (VT) エスケープ指定は不可 ("\u000B"で指定する)
\0nnn
(\1 ~ \9 は前方参照指定で使用するため) 0 で始まる 8 進値を 1 から 3 桁で指定する
\xhh
2 桁 (n 桁 \xhh… 指定は不可) の 16 進値
\uhhhh
16 進値 0xhhhh を持つ Unicode エスケープ
\/
スラッシュ文字 (/正規表現/ で使用する)
\"
二重引用符文字 ("正規表現文字列" で使用する)

並列プログラミング (Concurrent)

非同期計算スレッド (Futureタスク) を支援する関数は以下のとおり。

Barrier(n: Int)
n 個のスレッド (パーティの参加者) が共通のバリアーポイントに達するまで待機する 同期化支援機能を返す
Future(x: Function)
取り消し可能な非同期計算スレッド (Futureタスク) を開始して Futureタスクを返す
Cancel(a: Future)
Futureタスクの実行の取り消しを試みる
Join(a: Barrier)
バリアーポイントで待ち合わせる
Join(a: Future)
Futureタスクの終了を待機して 計算結果を返す
isAlive(a: Future)
Futureタスクが生存しているかどうかを返す

並列プログラミングを支援する関数は以下のとおり。

Channel()
スレッド間の通信に利用する リンクノードに基づく任意のバウンド形式の ブロッキング両端キューを返す
Range(start: Int, end: Int, step: Int*)
開始、終了、増分値で指定された 範囲を表す 整数値イテレータを返す
Sleep(second: Number)
現在実行中のスレッドを second秒 一時的にスリープする

タイプ (Types)

基本的な型は以下のとおり。

Boolean ブール型
Number 数値型の総称
  Int 短整数型の総称 (int, Integer)
  Double 実数または長整数型の総称 (Double, Float, Long)
String 文字列型の総称 (String, CharSequence)
AryMap 連想配列
Function 関数値
Reference 参照変数
AnyRef コンパイラに型推論を依頼する、推論できない場合は Object

AWK 関連リンク


Language Specification
  1. 言語仕様
    1. AWK プログラム (Program)
    2. パターン (Pattern)
    3. アクション (Action)
    4. コメント (Comments)
    5. 数値 (Numbers)
    6. 文字列 (Strings)
    7. 変数定義 (Variable declarations)
    8. 関数定義 (Function declarations)
    9. 関数呼び出し (Calls)
    10. 関数値 (Function value)
    11. 組み込み変数 (Builtin variables)
    12. 特殊ファイル名 (Special file name)
    13. 入出力 (Input/Output)
    14. 数値関数 (Numeric functions)
    15. 文字列関数 (String-Manipulation functions)
    16. ビット操作関数 (Bit-Manipulation functions)
    17. 時間関数 (Timestamp functions)
    18. 組み込みコマンド (Builtin Commands)
  2. 演算子 (Operators)
  3. 正規表現 (Regular Expressions)
  4. 並列プログラミング (Concurrent)
  5. タイプ (Types)
  6. AWK 関連リンク