awkの基本形
シェルに組み込むこともよくあるであろうスクリプト言語、awkについてあらためて
基本をまとめてみる。
awkの動作は次のようになっている。
1.オプションを解析し、初期設定を行う。
2.スクリプトの構文チェックを行い、エラーがあればエラーメッセージを出力して終了。
エラーがなければ次へ進む。
3.BIGINブロックがあればBIGINブロックの処理を行う。なければ次へ。
4.データを一行ずつ読み込み、対象データ(メインブロックに書かれた命令を読み込むデータ)
がなくなるまで1行ずつ実行する。
5.ENDブロックがあればENDブロックの処理を行う。
以下基本パターン。標準入力から入力された行がパターンに一致した場合、
その行に対してコマンドを実行する。一致しなければ何もしない。
awk ‘
/pattern/ {command}
‘
パターンを省略した場合はどの入力行に対しても実行される。
以下、代表的なパターン。

BIGINはスクリプトを初期化する働きがある。BIGINに伴うアクションは入力行が読み込まれる
前に処理されるため、タイトルや処理内容を表示させたり、各種変数を初期化する際に利用する。
以下はsample.txtのレコード区切りをタブに変更して全フィールドを出力。
$ awk ‘BEGIN {RS = “¥t”} {print $0} sample.txt
ENDに伴うアクションはawkが処理を終えた後に一度だけ実行される。
最終結果の出力や後処理を行うときに利用される。
以下はsample.txt全体のフィールド数を出力。
$ awk ‘{num+= NF} END {print num}’
//で囲むパターンには単純な文字列や数値の他、拡張正規表現を指定できる。
以下は単純にsample.txtからerrorを含む行の数を出力する。
$ awk ‘/error/{num++} END {print num}’ sample.txt
しかし、これだけなら$ grep error sample.txt | wc -l でもいい。
もっと複雑なことをやりたいときにawkを使うべきなのだろう。
以下、awkで定義されている変数。

オプションにより初期設定を変更したり、スクリプトファイルを利用できる。

awkのレコードとフィールドについて。
awkは標準入力や指定したファイルから1行分のデータを読み込むが、この1行分のデータを
レコードと呼ぶ。awkはレコード単位でデータを読み込み、フィールドと呼ばれる単位に
分割する。デフォルトではレコードの区切りは改行コード、フィールド区切りは1つ以上の空白となる。
これらはそれぞれ
RS(Record Separator)およびFS(Field Separator)で定義されている。
上の表にもあるように、フィールド区切りを変更したい場合は-Fオプションを利用する。
以下はsample.txtからフィールド区切りに「:」(コロン)を指定し、第1フィールドを出力。
$ cat sample.txt | awk -F: ‘{print $1}’
フィールド区切りに複数の文字を指定することも可能。
以下はコロンとピリオドの2つを指定し、タブ区切りで第3フィールドまで出力。
$ cat sample.txt | awk -F’[:.]‘ ‘{print $1 “¥t” $2 “¥t” $3}’
特定の行を取り出したい時。行はNRで定義する。
2行目のみ取得するには以下のように。
$ cat sample.txt | awk ‘(NR == 2)’
2行目の第5フィールドを取得。
$ cat sample.txt | awk ‘(NR == 2){print $5}’
デリミタ指定を入れる場合。
$ cat sample.txt | awk -F: ‘(NR == 2){print $5}’
ところでawkはターミナルで直接実行すればOKでも、ssh経由のコマンドやCronでは
動作しないことがある。スクリプトには {print $1} と書いているのにCronエラーで
{print /dev/null} と出力されたり。。なんなんだろう、あれ。
調べるのも面倒なので代替手段(cutコマンド)を使ってしまっているが、、、
主な出典
シェル&Perl入門(サイエンス社)