AWK(1)

awk

名称
awk - パターン指向型検索・処理言語

書式
awk [ -F fs ] [ -v var=value ] [ 'prog' | -f progfile ] [ file ... ]

解説
awk は prog または 1 つ以上の -f progfile の形式で指定されたファイルにおいて 指定されたパターンの組にマッチした行を逐語的に、各 file から検索します。 file の行がパターンにマッチした際に実行するアクションを、 各パターンに対して関連づけることができます。 各行は全てのパターン-アクション文におけるパターン部と比較され、 マッチしたパターンそれぞれに関連づけられたアクションが実行されます。 ファイル名 - は標準入力を意味します。 var=value 形式の file はファイル名でなく代入として扱われ、それがファイル名ならば 開かれるであろうタイミングで実行されます。 -v オプション の後に続く var=value は prog が実行される前に代入されます。 -v オプションはいくつあっても構いません。 -F fs オプションは入力フィールドセパレータを正規表現 fs に定義します。

入力行は通常空白または正規表現 FS によってフィールドに分解されます。 フィールドは $1, $2, ... で表され、 $0 は行全体を意味します。 FS がヌルだった場合には、入力行は一文字ごとにフィールドに分けられます。

パターン-アクション文は以下のような形式です

    pattern { action }

{ action } がない場合には、行を表示します。 pattern がなかった場合には、常にマッチします。 パターン-アクション文は改行またはセミコロンで分離されます。

アクションは文の並びです。 文は以下のうちのどれかです:

    if( 式 ) 文 [ else 文 ]
    while( 式 ) 文
    for( 式 ; 式 ; 式 ) 文
    for( var in array ) 文
    do 文 while( 式 )
    break
    continue
    { [ 文 ... ] }
    式	# 普通は var = 式
    print [ 式の並び ] [ > 式 ]
    printf format [ , 式の並び ] [ > 式 ]
    return [ 式 ]
    next	# この入力行に関して残りのパターンをスキップします
    nextfile	# このファイルの残りをスキップし、次を開き、先頭から始めます
    delete array[ 式 ]	# 配列要素を削除します
    delete array	# 配列の全ての要素を削除します
    exit [ 式 ]	# 直ちに終了します; ステータスは 式 です

文はセミコロン、改行、右かっこで終端されます。 空の 式の並び は $0 を意味します。 文字列定数は " " でくくられ、その中では通常の C エスケープが 解釈されます。 式は文字列や数値を適切に扱い、それらの文字列や数値は + - * / % ^ (指数) や(空白で示される) 結合演算子を使って組み立てられます。 ! ++ -- += -= *= /= %= ^= > >= < <= == != ?: 演算子も式の中で使用可能です。 変数はスカラー、 ( x[i] で表現される) 配列要素、またはフィールドです。 変数はヌル文字列で初期化されます。 配列の添字は数字である必要はなく、どのような文字列であっても構いません。 この機能により連想配列の形態をとることも可能になります。 [i,j,k] のように複数の添字を用いることも可能です。 構成要素は SUBSEP の値を使って結合されます。

print 文は与えられた引数を現在の出力フィールドセパレータを用いて 標準出力 (または >file あるいは >>file が使われていた場合にはファイル、 |cmd が使われていた場合にはパイプ) に出力し、 出力レコードセパレータによって終端します。 file と cmd はリテラル名または丸括弧でくくられた式であり、 異なる文での同一の文字列値は同じファイルをオープンすることを示します。 printf 文は引数のリストを書式 ( printf(3) 参照) に従って整形します。 組み込み関数 close(expr) はファイルまたはパイプ expr をクローズします。 組み込み関数 fflush(expr) はバッファリングされているファイルまたはパイプ expr をフラッシュします。

数学関数 exp, log, sqrt, sin, cos, atan2 は組み込みのものです。 その他の組み込み関数:

length
    引数または 引数がなかった場合には $0 を文字列として捉えた長さ。

rand
    (0,1) の乱数

srand
    rand 用の種を設定し、以前の種を返します。

int 整数値へ切り捨て

substr(s, m, n)
    s の 1 から数えて m 番目の位置から n-文字 の部分文字列。

index(s, t)
    s 中の文字列 t が現れる位置、現れなかった場合には 0。

match(s, r)
    s 中の正規表現 r が現れる位置、現れなかった場合には 0。 変数 RSTART と RLENGTH に、マッチした文字列の位置と長さがセットされます。

split(s, a, fs)
    文字列 s を配列要素 a[1], a[2], ..., a[n], に分割し、 n を返します。 分割は正規表現 fs または fs が与えられなかった場合にはフィールドセパレータ FS によって行われます。 フィールドセパレータが空の文字列だった場合、 文字列は1文字単位で配列要素へ分割されます。

sub(r, t, s)
    文字列 s 中に最初に現れた正規表現 r を t に置換します。 s が与えられなかった場合には、 $0 が用いられます。

gsub
    sub と同じですが、現れた全ての正規表現が置換されます。 sub と gsub は置換した数を返します。

sprintf(fmt, expr, ... )
    書式 fmt にしたがって expr ... を printf(3) で整形した結果の文字列

system(cmd)
    cmd を実行して終了状態を返却

tolower(str)
    str 中の全ての大文字を対応する等価の小文字に変換したコピーを返します。

toupper(str)
    str 中の全ての小文字を対応する等価の大文字に変換したコピーを返します。

``関数'' getline は現在の入力ファイルから次のレコードを $0 に設定します。 getline <file は file から次のレコードを $0 に設定します。 getline x の場合は代わりに変数 x に設定します。 最後に、 cmd | getline では cmd の出力を getline にパイプし、 getline のそれぞれの呼び出しは cmd の出力から次の行を返します。 全ての場合において、 getline は入力に成功すると 1 を返し、 ファイルの終端に達すると 0 を返し、 エラーになると -1 を返します。

パターンは任意の数の正規表現や関係式の ( ! || && による) 論理的組み合わせです。 正規表現は egrep のそれと同じです。 grep(1) を参照してください。 パターン中の単独 (isolated) 正規表現は行全体にかかります。 正規表現は ~ や !~ 演算子を用いて、関係式の中でも使えます。 /re/ は変化しない正規表現です。 パターン中の単独正規表現となる場所以外では、 どのような文字列 (定数または変数) であっても正規表現として使えます。

パターンはコンマで 2 つのパターンに区切ることができます。 この場合、1つ目のパターンと2つ目のパターンの間にある全ての行に対して アクションがなされます。

関係式は以下のうちのどれかです:

    式 matchop 正規表現
    式 relop 式
    式 in 配列名
    (式,式,...) in 配列名

ここで relop は C での 6つの関係演算子のどれか、matchop は ~ (マッチする) or !~ (マッチしない) のうち、どちらか。 条件は数式、関係式、またはこれらの論理的組み合わせのどれかです。

特別なパターン BEGIN と END は最初の行を読む前と最後の行を読んだあとに制御をつかむのに使用できます。 BEGIN と END は他のパターンと組み合わせることはできません。

特別な意味を持つ変数名:

CONVFMT
    数値を変換する際に使用する変換書式 (デフォルトでは %.6g)

FS  フィールド分離に使用する正規表現。 -Ffs オプションでも指定できます。

NF  現在のレコードでのフィールド数

NR  現在のレコードの序数

FNR 現在のファイルでの現在のレコードの序数

FILENAME
    現在の入力ファイルの名称

RS  入力レコードセパレータ (デフォルトでは改行)

OFS 出力フィールドセパレータ (デフォルトでは空白)

ORS 出力レコードセパレータ (デフォルトでは改行)

OFMT
    数値の出力書式 (デフォルトでは %.6g)

SUBSEP
    多次元配列のセパレータ (デフォルトでは 034)

ARGC
    引数のカウント、代入可能

ARGV
    引数の配列、代入可能。 ヌルでないメンバはファイル名として扱われます

ENVIRON
    環境変数の配列。添字は名前です。

関数は以下のように (パターン-アクション文の位置で) 定義できます:

    function foo(a, b, c) { ...; return x }

パラメータはスカラーの場合は値で、配列名の場合は参照で渡されます。 関数は再帰的に呼び出し可能です。 パラメータは関数ローカルで、それ以外の変数はグローバルです。 ローカル変数は関数定義時に余分なパラメータを加えることで作成できます。

使用例

length($0) > 72
72文字より長い行を表示します。

{ print $2, $1 }
始めの 2 フィールドを逆順で表示します。

    BEGIN { FS = ",[ \t]*|[ \t]+" }
          { print $2, $1 }

    同じですが、フィールドをコンマ、空白、タブで区切ります。

    	{ s += $1 }
    END	{ print "sum is", s, " average is", s/NR }

    1つ目のカラムを足していき、合計と平均を表示します。

/start/, /stop/
start と stop の組み合わせの間の行を表示します。

    BEGIN	{	# echo(1) をシミュレートします
    	for (i = 1; i < ARGC; i++) printf "%s ", ARGV[i]
    	printf "\n"
    	exit }

関連項目
lex(1), sed(1)
A. V. Aho, B. W. Kernighan, P. J. Weinberger, The AWK Programming Language, Addison-Wesley, 1988. ISBN 0-201-07981-X

バグ
数値と文字との間の明示的な変換はありません。 式を強制的に数値として扱わせるには、0 を足してください。 式を強制的に文字として扱わせるには、 "" を結合してください。
関数における変数のスコープ規則は不細工です。文法はさらにひどいです。