Language Specification

awk4j (AWK for Java Platform)

awk4j 言語仕様

awk4j は、一般的な AWK コマンドとの互換性を持っており、 "プログラミング言語AWK" の言語仕様 (awk95) の全てと GNU AWK の拡張機能の主要なものを実装している。

言語仕様の実装の差異を示すために、 このドキュメントで使用している記号の意味は以下のとおり。

# :
POSIX 標準に対する GNU AWK の拡張機能
♭ :
GNU AWK 独自の拡張機能で awk4j では未実装のもの
♪ :
awk4j 固有の拡張機能

AWK プログラム

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

パターン { アクション }
function name(parameter list) { statement }

パターン

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

BEGIN
END
/正規表現/
パターン && パターン
パターン || パターン
パターン ? パターン : パターン
! パターン
( パターン )
パターン , パターン
空のパターン

アクション

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

if (expression) statement [ else statement ]
while (expression) statement
for (expression; expression; expression) statement
for (var in array) statement
添字が選ばれる順序は、処理系の実現方法に依存
do statement while (expression)
switch (expression) { case expression or パターン: statement } [ default: statement ]
break
continue
delete array
delete array[expression]
exit [ expression ]
♪ 式の値が 0以外の場合は、System.exit() にて shellへの復帰値を設定する (JavaVM を終了) 制御の流れを変更する目的で使用する場合(BEGINからENDへの遷移など)は exit 0 ('0' の場合は exit を発行しない) の利用を推奨
{ statements }

コメント

コメントは、シャープ記号 (#) によって表わされ、 シャープ記号から、その行の終わりまでの全てがコメントとして扱われる。

♪ シャープ記号とパーセント記号 (#%) で始まるコメントは、埋め込みホストスクリプトとして解釈される。 (パターン部での指定は不可)
 (C言語: asm(), JSP: <%%>に相当する機能で、 トランスレータのオプション指定で組込みを指示をする)

組み込み変数

組み込み変数は以下のとおり。

ARGC
ARGV の要素数
ARGIND
配列 ARGV のインデックス (現在処理中のファイル名が格納されている要素を指す)
ARGV
コマンド行引数配列 (添字 1 より格納され、AWK へのオプションは含まない)
♪ ARGV[0] の内容は不定。 AWK(C言語インターフェイス) では実行プログラム名が格納されるが、 Java にはその概念はない
BINMODE #
♭ 入出力においてバイナリモードを制御 (Cygwin における行末の改行 "\n", "\r\n" 対策に相当)
CONVFMT
数値から文字列への変換書式 (既定値は %.6g)
ENVIRON
起動時の環境変数のコピー配列
♪ この配列要素の変更は、 リダイレクションや system 関数で起動されるサブプロセスの環境変数に反映される (shell の export コマンドに相当)
ERRNO
close およびファイル名指定の getline で例外発生時の理由を表わす文字列 (理由コードは非互換)
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"など) を制御するための配列 (UNIX プラットフォーム依存)
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" #
♭ RAW 通信 (/inet/raw/...) は未サポート
  • 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"
awk4j 拡張機能 による多重スレッド通信が可能
    リダイレクト指定は、 双方向パイプ(|&) を使用する
"jdbc:SUBPROTOCOL:SUBNAME [ ドライバパラメータ ... ] [ ;; SQL文 ]" ♪
  • jdbc:                 この URL が JDBC URL であることを表すスキーム名
  • SUBPROTOCOL: サブプロトコル (ドライバを識別する文字列)
  • SUBNAME:       接続先のホスト、データベース名称およびドライバオプション
  • ;; SQL文:          接続時に実行する SQL文 (オプション)
♪ jdbc URL 指定により一般ファイルインターフェイスにて、 SQL文による DBMSアクセスが可能
    リダイレクト指定は、 双方向パイプ(|&) を使用する
"http:// URL [ #文字コードセット ]" ♪
♪ URL より (文字コードを指定して) 読み込む
"file:// URL [ #文字コードセット ]" ♪
♪ ファイルURL に対して (文字コードを指定して) 入力または出力

入出力

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

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

Note: printf(): awk4j の変換書式は、 ANSI X3.159-1989 ('ANSI C') and ISO/IEC 9899:1999. のサブセットであり C言語の書式を受け付ける。

Note: system(): awk4j はコマンドラインの、 制御演算子 |, ;, new-line, | および リダイレクト演算子 >, >>, n>&m, n>>&m を受け付ける。

数値関数

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

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

文字列関数

文字列関数は以下のとおり。 (♪ パラメータは文字列以外に、数値およびオブジェクトも受け付ける)

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(str)
str を検査してその値を返す (str が"0"で始まる場合は、 8進数値, "0x"もしくは"0X"で始まる場合は、 16進数値)
sub(regexp, replacement [ , target ])
正規表現 regexp でターゲット文字列 target を replacement で置換し置換数を返す
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)
小文字をすべて大文字に変換した文字列を返す

Note: 文字列関数の位置および長さは、 バイト単位でなく文字であり、 ASCII コードを前提としているスクリプトは見直しが必要。

Note: tolower(), toupper(): は、 デフォルトロケール規則 (国際化対応) を使用して文字列を変換する。

ビット操作関数

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

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

時間関数

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

systime()
基準時点 (1970-01-01 00:00:00 UTC,) からの経過秒数(タイムスタンプ)を返す
mktime(datespec)
日付時刻を表す文字列をタイムスタンプに変換して返す
♭ ISO C標準ライブラリ仕様。引数は "YYYY MM DD HH MM SS [ DST ]" 形式の文字列
♪ Java "java.text.DateFormat" を実装。 引数は "2007/02/28 00:00:00" など (GNU AWK とは非互換)
strftime([ format [ , timestamp ] ])
指定したタイムスタンプ (省略時は現在時刻) を日付時刻を表す文字列に変換して返す
♭ GNU AWK は ISO C標準ライブラリ仕様。引数format省略時は、 "%a %b %d %H:%M:%S %Z %Y"
♪ Java "java.text.SimpleDateFormat" を実装。 format省略時は、Java デフォルトスタイル (GNU AWK とは非互換)

正規表現

awk4j の正規表現エンジン (Java クラス "java.util.regex") と GNU AWK 正規表現との非互換点について説明する。

エスケープシーケンス

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

Note: 非互換のエスケープシーケンスは修正が必要。

GNU AWK で拡張された正規表現

トランスレータは、以下の正規表現を変換する。

  1. /正規表現/ 形式の正規表現
  2. 以下の場所に現れる "正規表現文字列"

Note: 現在の AWK文法では、 /正規表現/ 形式の正規表現は、 数値または文字列が記述できる場所 (変数指定が必要な場所以外) であれば、 どこにでも記述可能であるが、 この単独で現れる /正規表現/ は、 ($0 ~ /正規表現/) と解釈されるため注意が必要である。

Tip: FS = /regexp/ は、 FS = ($ ~ /regexp/) の意味であり大方の期待とは異なる結果となる。
また、  var = FS = "regexp" でなく、  FS = var = "regexp" で間接代入した場合は トランスレータの変換対象とならない。

POSIX 文字クラス

英数字: [:alnum:]
\p{Alnum} または [\p{Alpha}\p{Digit}]
英字: [:alpha:]
\p{Alpha} または [\p{Lower}\p{Upper}]
空白またはタブ: [:blank:]
\p{Blank} または [ \t]
制御文字: [:cntrl:]
\p{Cntrl} または [\x00-\x1F\x7F]
10 進数字: [:digit:]
\p{Digit} または [0-9]
表示可能な文字: [:graph:]
\p{Graph} または [\p{Alnum}\p{Punct}]
英小文字: [:lower:]
[a-z]
プリント可能文字: [:print:]
\p{Print} または [\p{Graph}\x20]
句読文字: [:punct:]
\p{Punct} または !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
空白文字: [:space:]
\p{Space} または [ \t\n\x0B\f\r]
英大文字: [:upper:]
[A-Z]
16 進数字: [:xdigit:]
\p{XDigit} または [0-9a-fA-F]

アンカーなどのゼロ幅マッチ

単語の先頭: \<
(?<!\w)(?=\w)
単語の末尾: \>
(?<=\w)(?!\w)
入力(文字列)の先頭: \`  #
\A
最後の行末記号を除く入力(文字列)の末尾: \'  #
\Z
単語境界: \y #
\b

Tip: "{" は 範囲指定 {min, max} のメタキャラクタ
 文字として "{" を使用する場合は、エスケープ "\{" が必要
 GNU AWK でインターバルを使用する場合は --re-interval オプションを付けて実行する

Tip: 文字列の検索 /"([^"]|\\")*"/ は文字列に正しくマッチしない
 0長マッチに関する問題で、 /"(\\"|[^"])*"/ では不十分、 エンジンの実装に依存しない指定は、 /"[^"\\]*(\\"[^"\\]*)*"/ が正解


awk4j 拡張 (試験実装)

♪ awk4j では、 引数を 2個以上持つ system() 関数として実装しており 他の AWK言語との互換性は無い。

  1. 指示
    ENVIRON["/inet/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT"] = "接続待ち時間 入力待ち時間" ♪
    ソケット通信のタイムアウト時間を指定する (単位は秒、最小はミリ秒 0.001)
    ENVIRON["/inet/PROTOCOL/LOCAL-PORT/REMOTE-HOST/REMOTE-PORT" ".codeset"] = 文字コード ♪
    ソケット通信の送受信データの文字コードを指定する (UTF-8, EUC-JP, Shift_JIS など)
  2. スレッド
    system("Thread", "関数名" [ , 関数パラメータ ... ] ) ♪ (Java ホスト言語環境でのみ利用可能)
    新規のスレッド環境を生成して AWK関数の実行を開始する、生成したスレッドオブジェクトを返す
    ・多重スレッド環境での、グローバル変数の書き換え (レコード変数など) には注意すること
    system("cancel", スレッドオブジェクト ... ) ♪
    スレッドの実行取り消しを試みる (引数はスレッドオブジェクトを格納した配列指定も可)
    system("isAlive", スレッドオブジェクト ... ) ♪
    スレッドが生存しているかどうかを返す (引数は配列指定も可)
    system("join", スレッドオブジェクト ... ) ♪
    スレッドの完了を待ち合わせて、関数の復帰値を返す (引数は配列指定も可)
  3. バリア
    system("Barrier", パーティー数) ♪
    スレッド間で同期をおこなうためのバリアーポイントオブジェクトを返す
    system("join", バリアーポイントオブジェクト ... ) ♪
    このバリアーポイントにパーティーのメンバー(各スレッド)が揃うのを待ち合わせる
  4. その他
    system("sleep", 休止時間) または system("sleep 休止時間") ♪
    この関数を呼び出したスレッドの実行を一時的に停止する (単位は秒、最小はナノ秒 0.000001)

Undocumented Options and Features

Use the Source, Luke!
Obi-Wan

This minor node intentionally left blank.  (このセクションは、GNU AWK のドキュメントから拝借しました (^^)!)


AWK 関連リンク


Language Specification
  1. awk4j 言語仕様
    1. AWK プログラム
    2. パターン
    3. アクション
    4. コメント
    5. 組み込み変数
    6. 特殊ファイル名
    7. 入出力
    8. 数値関数
    9. 文字列関数
    10. ビット操作関数
    11. 時間関数
  2. 正規表現
    1. エスケープシーケンス
    2. GNU AWK で拡張された正規表現
  3. awk4j 拡張
  4. AWK 関連リンク