AWK
名前の由来は作者の3人の頭文字(Aho、Weinberger、Kernighan)から。
「おーく」と読む。
決して「えーい だぶりゅー けー」と読んではいけない。
AWK の誕生
たぶん「Version7 Unix」 といっしょに配布されたと考えられる。
AWK の特徴
awkは、ファイルの中から指定した
パターンを含む行を検出し、それに対して、
特定の処理を行うことができる。
awkはUnix上で開発されたので、いくつかの特徴は、
通常はUnixでしか見つけられない機能を反映している。
awkは
完璧ではない。この言語は、不揃いや手抜き、それにまったく悪いアイディアとしか言いようがないものも受け継いでいるうえに、ときには耐えられないほど遅い。
書式
awk [-F '文字'] 'プログラム' [ファイル名 ...]
awk [-F '文字'] -f プログラムファイル [ファイル名 ...]
文字列定数
文字列定数表記 | 文字コード | 意味 |
\a | 0x07 | 警告(ベル) |
\b | 0x08 | バックスペース |
\f | 0x0c | 改頁(フォームフィード) |
\n | 0x0a | 改行(ニューライン) |
\t | 0x0d | 水平タブ |
\r | 0x09 | キャリッジリターン |
\v | 0x0b | 垂直タブ |
\xhh | | 16進数hhで表現される文字 |
\ooo | | 8進数oooで表現される文字 |
\c | | 上記以外の文字cそのもの |
定義済みファイル名
/dev/null
どこからも入力されない。どこにも出力されない。
/dev/tty
コンソール出力
/dev/stdin
標準入力("/dev/fd/0" と同じ)
/dev/stdout
標準出力("/dev/fd/1" と同じ)
/dev/stderr
標準エラー出力("/dev/fd/2" と同じ)
/dev/fd/n
ファイル番号nで表されるファイル
/dev/pid
自分のPIDが読み出せる
/dev/ppid
親プロセスのPIDが読み出せる
/dev/pgpid
自分のグループID(GID)が読み出せる
/dev/user
システムコール getuid getueid getgid getegid getgroups の返り値が、それぞれフィールドに区切られて読み出せる。ただし、getgroupsはサポートされている場合のみである。
正規表現
演算子(式演算子)
演算子$ | フィールド参照 |
++ -- | インクリメント、デクリメント |
^ | 累乗 |
+ - ! | 単項演算子 |
* / % | 積、商、剰余 |
+ - | 和、差 |
(空白) | 文字列連接(ex. "ABC" "DEF") |
<<= >>= != == | 関係演算子 |
~ !~ | 正規表現適合、非適合 |
in | 配列要素 |
&& | 論理積 |
|| | 論理和 |
?: | 三項演算子 |
= += -= *= /= %= ^= | 代入 |
AWKのパターン
パターンでは、awkで式として
評価されるものはすべて許容される。 パターンを省略するとすべての行が対象になる。
すべての入力を読み終わった後に文が一度実行される。
式が真、すなわち非零か非空列である各入力行に対して文が実行される。
正規表現に適合するような文字列を含む各入力行に対して文が実行される。
複合パターンは、式を&&(かつ) 、||(または)、 !(~でない)、 それにかっこを使って結合されたものである。
複合パターンが真である各入力行に対して文が実行される。
範囲を示すパターンは、パターン1に適合する行からパターン2に適合する次の行(この行を含む)までの各入力行に適合する。
適合した各行に対して文が実行される。
パターン1 と パターン2の両方が同じ行に現れた場合は、その1行にだけ適合する。
制御文
if ( 式 ) 文1 [else 文2]
式が真なら文1を実行、式が偽ならば文2を実行する
while ( 式 ) 文
式が真の間、文を実行する
do 文 while ( 式 )
for( 式1; 式2; 式3) 文
式1が初期値、式3が増分のとき式2が真の間、文を実行する
`for( 変数 in 配列) 文
変数に連想配列の添え字がひとつづつ入り、文を実行する
break
while文、またはfor文を終了する
continue
while文、またはfor文で、次の繰返しを開始する
next
スクリプトの最初のに戻り、次のレコードを読み込む
next file
スクリプトの最初のに戻り、次のファイルの先頭レコードを読み込む
exit[式]
スクリプトを終了する。
ENDルールがあればそれを実行する
return[式]
ユーザー定義関数の終了。
式があれば、その値を返す
入出力文
スクリプト中で何も指定しない場合、getline文の入力は処理中の入力ファイル(組込変数FILENAMEの値)または標準入力から読み込まれ、print文 や printf文 の出力は、標準出力に書き込まれる。
これらは、以下のように指定することによって入力元および出力先を変更することができる。
print > <ファイル>
出力は<ファイル>に上書きされる
print >> <ファイル>
出力は<ファイル>に追加される
print | <コマンド>
出力は<コマンド>の標準入力として渡される
getline < <ファイル>
入力は<ファイル>から読み込まれる
<コマンド> | getline
入力は<コマンド>の標準出力が読み込まれる
組み込み変数
ARGC
コマンドライン引数の数。
awk 自身に対するコマンドラインオプションは数に含まれない。
ARGIND
現在処理中の ARGV
へのインデックス。
ARGV[ARGIND]
は現在処理中のファイル名を表す。
つまり、 FILENAME
と ARGV[ARGIND]
は常に同じになる。
ARGV
コマンドライン引数の配列。
配列の要素は0から始まり ARGC-1まである。
0番目の要素にはawkプログラム自身の名前が格納される。
ARGV
の内容を変更することにより、処理するファイルを変更できる。
CONVFMT
数値を文字列に変換するときに使用される書式。
デフォルト値は"%.6g"である。
ENVIRON
環境変数の連想配列。
この配列の内容を変更しても他のプロセスには影響が無い
ERRNO
getline や close でエラーが発生したとき、エラーの内容を表す文字列が格納される
FIELDWIDTHS
この組み込み変数に値が代入されると、awk 入力レコードを固定長フィールドからなるものとして扱う。
値は各フィールドの長さ(バイト単位)を空白で区切って指定する。
FILENAME
現在処理中のファイル名。
標準入力から読み込んで処理している場合、 FILENAME
の値は '-' になる
FNR
現在処理中のファイル先頭からのレコード番号
FS
入力フィールドセパレータの値。
デフォルトの値はブランク(" ")である。
IGNORECASE
大文字小文字識別フラグ。
IGNORECASE
の値が0以外の場合、awkはパターンマッチのときに大文字と小文字の識別を行わず同じ文字として扱う。
NF
処理中のレコードにおけるフィールドの数
NR
今まで処理したレコードの総数
OFMT
数値を文字列に変換するときに使用される書式。
デフォルト値は"%.6g"である。
OFS
出力フィールドセパレータの値。
デフォルトの値はブランク(" ")である。
ORS
出力レコードセパレータの値。
デフォルトの値は改行文字("\n")である。
RS
入力レコードセパレータの値。
RS
の先頭の1文字だけが用いられる。
デフォルトの値は改行文字("\n")である。
RLENGTH
直前のmatch関数で指定した正規表現に一致した部分文字列の長さが格納される。
一致するものがない場合、-1 が格納される。
RSTART
直前のmatch関数で指定した正規表現に一致した部分文字列の位置が格納される。
一致するものがない場合、0 が格納される。
SUBSEP
配列の添え字の区切り文字。
デフォルト値は、"\34" である。
組み込み文字列関数
gsub( 正規表現, 置換文字列)
gsub( 正規表現, 置換文字列, 対象文字列)
対象文字列中で正規表現に一致する部分文字列をすべて置換文字列に置換し、置換された数を返す。
対象文字列を省略した場合、代わりに $0 が使われる。
置換文字列中の'&'は、正規表現に一致した部分文字列に置き換えられる。
置換文字列中に'&'そのものを含めたい場合は、'\\&'と書かなければならない。
subは、正規表現に最初に一致した部分文字列のみを置換するのに対して、gsubは一致した部分文字列すべてを置換する。
つまり、gsubの'g'は'grobal'の意味である。
index( 部分文字列, 対象文字列)
対象文字列の中の部分文字列の位置をバイト単位で返す。
対象文字列が部分文字列を含まない場合は0を返す。
length( 対象文字列)
対象文字列の長さをバイト数で返す。
対象文字列を省略した場合、代わりに $0 が使われる。
漢字コードには対応していない場合があるので注意すること。
match( 対象文字列, 正規表現)
対象文字列の中で、正規表現に一致する位置をバイト単位で返し、一致した部分文字列の位置と長さを組み込み変数
RSTART
と
RLENGTH
に
格納する。
一致するものがない場合0を返す。
split( 対象文字列, 配列)
split( 対象文字列, 配列, 正規表現)
対象文字列を正規表現で分割し、配列に格納する。
戻り値として分割数を返す。
ただし、対象文字列に空文字を指定した場合は 0 となる。
正規表現を省略した場合、代わりに組み込み変数 FS
が使われる。
sprint( 書式, 式の並び)
「式の並び」をprintf と同様の書式にしたがって変換した文字列を返す。
「式の並び」はコンマ","で区切って書式に対応した数だけ指定する。
sub( 正規表現, 置換文字列)
sub( 正規表現, 置換文字列, 対象文字列)
対象文字列中で、正規表現に最初に一致する部分文字列を置換文字列に置換し、置換された数、つまり1または0を返す。
対象文字列を省略した場合、代わりに $0 が使われる。
置換文字列中の'&'は、正規表現に一致した部分文字列に置き換えられる。
置換文字列中に'&'そのものを含めたい場合は、'\\&'と書かなければならない。
gsubは一致した部分文字列すべてを置換するのに対して、subは、正規表現に最初に一致した部分文字列のみを置換する。
substr( 対象文字列, 開始位置)
substr( 対象文字列, 開始位置, バイト数)
対象文字列の中のバイト単位で指定した開始位置からバイト数分の部分の部分文字列を返す。
バイト数を省略した場合、対象文字列の開始位置から最後までを返す。
入力行の総数を印字する。
10行目の入力行を表示する。
すべての入力行の最後の欄を表示する。
最後の行の最後の欄を表示する。
AWK{ fild = $NF }
END { print $NF}
4個より多い欄を持つすべての入力行を表示する。
最後の欄が4より大きようなすべての入力行を印字する
すべての入力行の欄の総数を印字する。
AWK{ nf = nf + NF }
END { print nf}
Beth を含む行の総数を表示する。
AWK/Beth/ { nlines = nlines +1}
END { print nlines }
最も大きい第1欄とそれを含む行を表示する。($1のどれかは正であると仮定する)
少なくとも一つの欄を持つすべての行を表示する。
80文字以上の長さを持つすべての行を表示する。
それぞれの行の欄の数とその行自体を表示する。
任意の行を最初のふたつの欄を逆順で表示する。
すべての行を最初のふたつの欄を逆順で表示する。
AWK{ temp = $1; $1 = $2; $2 = temp; print }
すべての行を最初の欄を行番号に置き換えて表示する。
すべての行を二つ目の欄を消去して表示する。
すべての行の欄を逆順で表示する。
AWK{ for( i = NF; i > 0; i = i - 1)printf("%s ",$i)
printf("\n")
}
すべての行の各欄の合計を表示する。
AWK{ sum = 0
for( i = 1; i <= NF ; i = i + 1)sum = sum + $i
print sum
}
すべての行のすべての欄を合計して、その値を表示する。
AWK { for( i = 1; i <= NF ; i = i + 1)sum = sum + $i }
END { print sum }
各欄の値を絶対値に置き換えてからすべての行を表示する。
AWK{ for( i = 1; i <= NF ; i = i + 1) if($i < 0) $i = -$i
print
}