AWKとは、文字列の検索、抽出、変換及び置き換えに長けたプログラミング言語です。おもにテキストファイルから一部分を抜き出したり、書式を変換するのに使われます。

スポンサーリンク

AWKのインストール方法

Unix

たいていのUnixには、あらかじめawkがインストールされている。ただし、awkより高機能なGNU版awk「gawk」をインストールすることもできる。

Microsoft Windows

Microsoft WindowsではGNU版awkであるgawkを使用できる。gawkのインストール方法を示す。

  1. ウェブブラウザでGawk for Windowsを開く。
  2. 「Complete package, except sources」の「Setup」をクリックする。
  3. 自動的にインストーラのダウンロードが始まる。
  4. ダウンロードしたインストーラを実行する。
  5. Gawk for Windowsがインストールされる。
  6. 環境変数のPATHにGawk for Windowsの実行ファイルフォルダ(C:\Program Files (x86)\GnuWin32\bin)を追加する。

実行方法

awkはファイルを走査し、指定したパターンのいずれかと一致する行を探します。一致する行が見つかったときに指定されたアクション(動作) を実行します。

実行形式には、スクリプトを引数として指定する方法と、スクリプトを格納したファイルの名前を引数で指定する方法があります。

スクリプトを引数として指定する場合、シェルからawkコマンドを次のように実行します。

awk 'スクリプト' [ 入力ファイルのパス ]

入力ファイルのパスは省略可能です。省略した場合は、標準入力が対象となります。

あらかじめスクリプトを格納したテキストファイルを作成しておき、そのスクリプトファイルの名前を引数で指定する方法の場合、シェルからawkコマンドを次のように実行します。

awk -f スクリプトファイルのパス [ 入力ファイルのパス ]

スクリプトファイルの拡張子にとくに決まりはありません。

gawkコマンドの使い方

gawkコマンドはGNU版のAWKである。LinuxやWindowsなどさまざまなOSで使うことができる。

スクリプトをgawkコマンドの引数に指定して実行する場合の構文は次のとおり。

gawk [options] [--] 'program-text' [file ...]

あらかじめスクリプトを記述したファイルを用意しておき、gawkコマンドの引数にそのファイルパスを指定して実行する場合の構文は次のとおり。

gawk [options] -f program-file [--] [file ...]

program-text にはawkのプログラムを指定する。

gawkに指定できるオプションを示す。

-F field-separator

入力のフィールド区切り文字を指定する。

-f program-file

awkのプログラムファイルを指定する。

パターンとアクション

スクリプトはテキストの置換・抽出・変換などのルールを指定するもので、パターン文とアクション文から成り立ちます。スクリプトは次の形式で記述します。

pattern { action }

入力行をパターンと比較して一致したら、アクション文を実行します。 パターンは正規表現で記述することができます。

awk '/井上/ { print $0 }' 住所録

上記の例では、住所録ファイル内で「井上」という文字列を含む行を出力しています。

パターン

パターンは次の3種類で表します。

任意の文字列を正規表現で表すことができます。

/正規表現/

行の末尾は $ で表します。たとえば、最後が mi で終わる行は mi$ と表せます。

$ cat member
umeda erika
yajima maimi
nakajima saki
$ awk '/mi$/ { print $0 }' member
yajima maimi
$

特別なパターンとして、BEGINEND があります。 BEGIN パターンのアクションには、最初の行を読み込む前に実行する処理を記述します。 END パターンのアクションには、最後の行を読み込んだ後に実行する処理を記述します。

BEGIN { print "*** start ***" }
{ print $0 }
END { print "*** end ***" }

awkの組み込み変数

awkにはあらかじめ定義されている組み込み変数がある。

awkの組み込み変数
組み込み変数 説明 デフォルト値
FILENAME 現在の入力ファイル名 "-"
RS 入力のレコード区切り文字 改行(\n)
FS 入力のフィールド区切り文字 スペース
ORS 出力のレコード区切り文字 改行(\n)
OFS 出力のフィールド区切り文字 スペース
NR 現在のレコード数
NF 現在のレコードのフィールド数
$0 現在の入力レコード
$n 現在の入力レコードにおけるn番目のフィールド

変数

awkにおける変数の命名規則は次のとおり。

変数に値を代入するには「=」を使う。また、awkでは配列を使うこともできる

BEGIN {
    x = 10
    y = "foo"
    z[1] = 1
    z[2] = 2
    print x
    print y
    print z[1]
    print z[2]
}

awkでは連想配列を使用できる。

$ cat order.txt
apple 10
grape 3
orange 5
apple 7
orange 3
$ cat order.awk
{ order[$1] += $2 }
END {
  for (x in order) print x " " order[x]
}
$ gawk -f order.awk order.txt
apple 17
orange 8
grape 3
$

AWKの組み込み関数

AWKには次表に示す組み込み関数がある。

AWKの組み込み関数
関数 説明
cos 余弦(コサイン)を返す。
exp 指数を返す。
getline 次のレコードを読み込む。
index 指定した文字列が最初に出現する位置を返す。
int 小数点以下を切り捨てた整数を返す。
length 文字列の長さ(文字数)を返す。
log 自然対数を返す。
match 指定した正規表現が最初に出現する位置を返す。
sin 正弦(サイン)を返す。
split 文字列を配列要素に分解して、その要素数を返す。
sprintf 書式に従って文字列に変換する。
sqrt 平方根を返す。
substr 部分文字列を返す。

cos

余弦(コサイン)を返す関数です。

number cos(number)

exp

指数を返す関数です。

number exp(number)

getline

number getline()

現入力ファイルの次のレコードを組み込み変数 $0 に設定します。getline 関数は正常終了時には1を、ファイルの終わりに達すると0を、エラー発生時には-1を返します。

index

number index(string, substring)

文字列 string の中で文字列 substring が最初に出現する位置を返します。出現しなければ0を返します。

int

小数点以下を切り捨てた整数を返す関数です。

number int(number)
number int(string)

length

引数で指定した文字列の長さ(文字数)を返す。

number length([string])
string
長さ(文字数)を調べる文字列を指定する。stringの指定を省略した場合、$0(レコード全体)の長さが返る。

log

自然対数を返す関数です。

number log(number)

match

awk

match(string, regexp)

gawk

match(string, regexp[, array])

文字列stringの中で正規表現regexpが最初に出現する位置(1〜)を戻り値として返す。regexpにマッチする文字列が存在しなければ戻り値として0を返す。

sin

number sin(number)

number の正弦(サイン)を返す関数です。

split

number split(string, array, fs)

文字列 stringarray[1]array[2]、...、array[n] の配列要素に分割して、値 n を返します。この分割は正規表現fs によって行われ、fs が指定されていない場合はフィールドセパレータによって行われます。

$ cat split.txt
foo:bar baz:qux
$ cat split1.awk
{
  n = split($0, a)
  print n
  for (i in a) {
    print a[i]
  }
}
$ awk -f split1.awk split.txt
2
foo:bar
baz:qux
$ cat split2.awk
{
  n = split($0, a, ":")
  print n
  for (i in a) {
    print a[i]
  }
}
$ awk -f split2.awk split.txt
3
foo
bar baz
qux
$

sprintf

string sprintf(format, expr, expr, ...)

format で指定した printf 形式に従って式の書式を定め、文字列を返します。

sqrt

number sqrt(number)

number の平方根を返す関数です。

substr関数

string substr(string, m[, n])

文字列 string 内の m 番目から始まる長さ n の部分文字列を返します。

ユーザ定義関数

awkではユーザが独自の関数を定義することができる。関数の定義は次の書式で記述する。

function name([parameter[,parameter...]]) {
    statements
    return expr
}

awkにおける関数の引数は値渡しである。参照渡しにすることはできない。ただし、awkの変数はすべてグローバル変数なので、関数内で設定した変数を関数の外で参照できる。また、関数の外で設定した変数を関数内で参照できる。

関数の呼び出しは次の書式で記述する。

name([argument[,argument...]])

awkの関数は再帰呼び出し(関数の中でその関数自身を呼び出す)も可能である。

アクション

アクションは一連の文です。使用できる文は次のうちのいずれかです。

if

ifは条件分岐を行う制御構文である。

if (condition) then-body [else else-body]

conditionには条件式を指定する。条件式には比較演算子や論理演算子を使うことができる。

if (x % 2 == 0)
    print "xは偶数です。"
else
    print "xは奇数です。"

改行を入れずに1行で記述することもできる。ただし、この場合はthen-bodyとelseをセミコロンで区切る必要がある。

if (x % 2 == 0) print "xは偶数です。"; else print "xは奇数です。"

比較演算子

awkの比較演算子
比較演算子 説明
expr1 == expr2 expr1expr2が等しい
expr1 != expr2 expr1expr2が等しくない
expr1 < expr2 expr1expr2より小さい
expr1 <= expr2 expr1expr2以下
expr1 > expr2 expr1expr2より大きい
expr1 >= expr2 expr1expr2以上

論理演算子

awkの論理演算子
論理演算子 説明
expr1 && expr2 論理積
expr1 || expr2 論理和
!expr 否定

while

while (condition) statement
while (condition) { statements }
condition

繰り返しを続行する条件を指定する。条件が真である間、処理を繰り返す。whileループは処理を実行する前に繰り返し条件をチェックする前判定である。つまり、一度も処理を実行しないこともある。

do

do statement while (expression)
do { statements } while (expression)
condition

繰り返しを続行する条件を指定する。条件が真である間、処理を繰り返す。doループは処理を実行した後に繰り返し条件をチェックする後判定である。つまり、必ず一度は処理を実行する。

for

for (initialization; condition; increment) statement
    
for (initialization; condition; increment) { statements }
for (var in array) statement
    
for (var in array) { statements }
initialization

繰り返し処理を始めるときに一度だけ実行する処理を指定する。たいていはループカウンタの初期化を行う。

condition

繰り返しを続行する条件を指定する。たいていはループカウンタが上限値を超えていないことのチェックである。条件が真である間、処理を繰り返す。forループは処理を実行する前に繰り返し条件をチェックする前判定である。つまり、一度も処理を実行しないこともある。

increment

次の繰り返しに移るたびに実行する処理を指定する。たいていはループカウンタのインクリメント(+1)である。

for (i in a) {
    delete a[i]
}

printfを用いたAWKのサンプルを示す。

$ cat factorial.txt
1
3
5
$ cat factorial.awk
{
  f = 1
  for (i = 2; i <= $1; i++) {
    f = f * i
  }
  print $1 "の階乗は" f
}
$ awk -f factorial.awk factorial.txt
1の階乗は1
3の階乗は6
5の階乗は120
$

break

break

if、while、do、for の処理を中止します。

continue

現在の繰り返し処理を中断して、次の繰り返し処理にスキップする。

continue

print

print [expr [expr]...] [>|>> filename]
print [expr [,expr]...] [>|>> filename]
expr

標準出力に出力する式を指定する。exprを省略した場合は現在のレコード($0)を出力する。出力されるレコードの最後にはORSの値が付加される。

expr を空白で区切って複数指定した場合、連結されて出力される。たとえば、 print "a" "b" "c" print "abc" と同じである。

expr をカンマで区切って複数指定した場合、空白で区切られて出力される。たとえば、 print "a", "b", "c" print "a b c" と同じである。

filename
出力をリダイレクトする場合、リダイレクト先を指定する。

ファイルfoo.txtへ出力する例を示す。

print "Hello, world!" > foo.txt

ファイルfoo.txtへ追加出力する例を示す。

print "Hello, world!" >> foo.txt

printf

printfは、書式にしたがって文字列に変換し、標準出力に出力する。

printf format [,expr...] [>|>> filename]
format

書式を指定する。書式にはメタ文字を使用できる。

printfのメタ文字
メタ文字 説明
%c ASCIIの1文字
%d 整数
%nd n桁の整数
%0nd n桁の整数(桁数がnに満たない場合は0で埋める)
%f 浮動小数点
%e 指数形式
%o 符号なし8進数
%s 文字列
%ns n桁の文字列
%% 「%」という文字そのもの
expr

書式で使用する値。リテラル、変数、関数又は計算式などを指定する。

$ cat printf.txt
65 foo
$ cat printf.awk
{printf "%c %d %04d %f %e %o %s %%", $1, $1, $1, $1, $1, $1, $2}
$ awk -f printf.awk printf.txt
A 65 0065 65.000000 6.500000e+01 101 foo %
$

next

next

現在の入力レコードの処理を終了して、次の入力レコードに進む。

exit

残りの入力を飛ばして、ENDアクションを実行する。ENDアクションの中でのexitステートメントでは、さらにENDアクションが呼び出されることはない。

exit [ 終了ステータス ] 

delete

deleteステートメントは、配列のキーと値を削除する。

delete array[expr]

for (i in a) {
    delete a[i]
}
スポンサーリンク

関連コマンド

sed

$0

組み込み変数 $0 は、入力行(レコード)を表します。

$n

組み込み変数 $n は、n番目のフィールドを表します。

最初の2フィールドを逆順に出力する例を次に示す。

$ awk '{ print $2, $1 }' member
erika umeda
maimi yajima
saki nakajima

FILENAME

組み込み変数 FILENAME は、現入力ファイル名を表します。

$ awk '{print FILENAME}' foo.txt
foo.txt
$

FS

組み込み変数 FS は、入力フィールドセパレータの正規表現を表します。

入力フィールドのコンマで区切り、最初の2フィールドを出力する例を次に示す。

BEGIN { FS = "," }
{ print $1, $2 }

ダブルクォーテーション(")で区切り、4番目のフィールドを出力する例を次に示す。

awk 'BEGIN {FS="\""} {print $4}' text

NF

組み込み変数 NF は、現レコード中のフィールド数を表します。

NR

組み込み変数NRは、現レコード番号を表します。

特別パターン END においては現レコード番号は最後のレコード番号となりますので、つまり全レコード数(入力ファイルの行数)となります。

行番号と入力行を出力するawkスクリプトの例を示す。

$ awk '{ print NR, $0 }' member
1 umeda erika
2 yajima maimi
3 nakajima saki

2番目のフィールドを合計して、合計値と平均値を出力するAWKのサンプルを示す。

$ cat foo.txt
foo 30
bar 50
baz 100
$ cat foo.awk
{ sum += $2 }
END {
  print "合計値", sum
  print "平均値", sum / NR
}
$ awk -f foo.awk foo.txt
合計値 180
平均値 60
$

OFMT

組み込み変数 OFMT は、数値の出力形式を表します。

OFS

組み込み変数 OFS は、出力フィールドセパレータを表します。

ORS

組み込み変数 ORS は、出力レコードセパレータを表します。

RS

組み込み変数 RS は、入力レコードセパレータを表します。

入力ファイル/etc/passwdからユーザIDとユーザ名を出力する例を示す。

$ gawk -F: '{print $3 " " $1}' /etc/passwd
0 root
1 bin
2 daemon
3 adm
4 lp
スポンサーリンク