概要
AWKは文字列の検索、抽出、変換などができるプログラミング言語です。
Unix、Linuxは基本的にテキストをプロトコルとしています。AWKを扱えるとそのプロトコルをより柔軟に扱えることになります。
前提知識
あらかじめ知っておくべき知識を書いていきます。
パターンとアクション
awkの書式は以下のようになっています。
$ awk 'パターン {アクション}'
パターンとアクションは両方同時に書く必要はなく、以下のようになります。
ケース | どうなるか |
---|---|
アクションのみ | 全てのレコードに対してアクションが実行される |
パターンのみ | パターンにマッチしたレコードを表示する |
パターンもアクションもない | 何も表示されない |
アクションのみの場合はこんな感じに書きますし、
$ echo "a b c" | awk '{print $0}' a b c
パターンのみの場合はこんなふうに書きます。
$ seq 1 10 | awk '$0 % 2 == 0' 2 4 6 8 10
AWKの要素は1から数える
大抵のプログラミング言語ではarrayなど要素は0から始まりますが、awkは1から始まります。
$ echo "a b c d" | awk '{print $1}' a
$0
はレコード全体を表示します。
$ echo "a b c d" | awk '{print $0}' a b c d
AWKの真偽値
真偽値のルールは以下です。
- 数字の
0
は偽 - 空文字列は偽
- それ以外は真
# 数字の0 $ echo "foo" | awk '0' # 0じゃない数字 $ echo "foo" | awk '2' foo # 空文字列 $ echo "foo" | awk '""' # 空じゃない文字列 $ echo "foo" | awk '"bar"' foo
代入の戻り値は左辺値
代入のケースは少し特殊です。AWKは破壊的な代入が可能ですが、戻り値は左辺の値になります。
# 左辺値はBなので真 $ echo "a b c" | awk '$2 = "B"' a B c # 左辺値が空文字だから偽 $ echo "a b c" | awk '$2 = ""'
組込変数
AWKにはあらかじめいくつかの組込変数が用意されています。
組込変数 | 説明 | デフォルト値 |
---|---|---|
RS | Record Separator 入力のレコード区切り文字 |
改行 |
FS | Field Separator 入力のフィールド区切り文字 |
連続するスペースorタブ文字 |
ORS | Output Record Separator 出力のレコード区切り文字 |
改行 |
OFS | Output Field Separator 出力のフィールド区切り文字 |
スペース1つ |
NR | Number of Record 現在のレコード数 |
|
NF | Number of Field 現在のレコードのフィールド数 |
基本的な使い方
検索
/
で囲んだ正規表現で記述できます。
$ echo "foo bar baz" | awk '/foo/' foo bar baz
ちなみにこれは実は$0 ~
を省略したシンタックスシュガーです。なので
$ echo "foo bar baz" | awk '$0 ~ /foo/' foo bar baz
これと同じです。
文字列の抜き出し
substr()
を使います。
# 開始文字のみ指定 $ echo "abcde" | awk '{print substr($0, 2)}' bcde # 開始文字〜何文字まで抜き出すか指定 $ echo "abcde" | awk '{print substr($0, 2, 3)}' bcd
連接
AWKで文字列を繋げる(連接する)場合は文字列の間にスペースを置きます。
$ echo "abc" | awk '{print $0 "def" "ghi"}' abcdefghi
sprintf()
でフォーマット指定もできます。
$ echo "abc" | awk '{print sprintf("%s%s%d", $0, "def", 5)}' abcdef5
置換
最初にマッチした文字列だけ置換するsub()
や、マッチした全ての文字列を置換するgsub()
があります。
# sub() $ echo 'abcde' | awk '{sub(/./, "A"); print $0}' Abcde # gsub() $ echo 'abcde' | awk '{gsub(/./, "A"); print $0}' AAAAA
インプットのField Separatorを変更する
-F
を使います。例えばCSVファイルを扱いたい場合は
$ echo 'a,b,c' | awk -F "," '{print $2}' b
のようにします。
※他の変数は-v
オプションで指定するのに対し、変数FSだけはこのように-F
オプションで直接指定できます。
アウトプットのField Separatorを変更する
OFS
を使います。ただこれだけではうまくいきません。
$ echo 'a b c' | awk -v OFS=',' '{print $0}' a b c
これは"a b c"を読み込んだ際にAWKがフィールド分割を行なっているだけで、新しくフィールドの再構築を行なっていないためです。フィールドの再構築をするには$1 = $1
という特殊な書き方をします。
$ echo 'a b c' | awk -v OFS=',' '{$1 = $1; print $0}' a,b,c