02 月 06 日(月)
AWK の配列をうまく使えば,複雑な処理を簡単に記述できる場合がある.
AWK の第一歩 や gawk 日本語マニュアル 等を参考にしながら, 作業を進めて行こう.
AWK では,変数と同様に,配列についても宣言せずに利用できる. つまり,AWK の配列は, 動的配列(要素数が可変の配列)ということだ.
配列の簡単な使用例として次のスクリプト reverse.awk を試してみよう:
#!/usr/bin/awk -f { line[NR] = $0; } # 配列 line[ ] に全レコードを記録 END { # 配列 line[ ] の全要素を逆順で出力 for (i = NR; i >= 1; i--) { print line[i]; } }
これは,レコードの順序を反転して出力する. たとえば,このスクリプトファイル自身を入力にして, 実行してみよう:
$ ./reverse.awk reverse.awk } } print line[i]; for (...) { ... #!/usr/bin/awk -f
AWK は,データ型を持たず, すべてのデータを(基本的には)文字列として取り扱う. なんと,配列要素の添え字(要素番号)でさえも,文字列が利用される.
このような文字列を添え字とする配列...連想配列は, 対応表(2フィールドのテーブル)データ等を処理対象とする場合, とても都合がよい. たとえば,食品の名前と色の対応表を次のように記述できる:
# AWK 版の対応表データ(連想配列) color["apple"] = "red"; color["bacon"] = "pink"; color["coffee"] = "black"; ...
「apple の色は red です」という意味.
考え方としては,「配列」というより,「構造体」に近いかも... 場合によっては,次のような使い方もあり得る:
apple["color"] = "red"; apple["shape"] = "sphere"; ...
上の例をC言語で記述してみれば, 連想配列の便利さがよくわかるだろう. Cでは,次のように2つの配列を準備しなければならない:
// C 言語版の対応表データ(2配列) name[0] = "apple"; color[0] = "red"; name[1] = "bacon"; color[1] = "pink"; name[2] = "coffee"; color[2] = "black"; ...
「0番の物の名前は apple,0番の物の色は red です」という意味.
もちろん,構造体を使えば1つの配列でも実現できるが... 2つのメンバ変数を準備しなければならない:
item[0].name = "apple"; item[0].color = "red"; ...
そして,たとえば,"coffee" の色を調べるには, Cの場合:
という2段階の手順が必要となるが, 検索処理のコードを書くのは面倒だ..
一方,AWK の連想配列なら,color["coffee"] と書くだけで済む. 面倒な検索処理をわざわざ記述する必要はない. AWK が自動的に検索してくれるんだ.
連想配列のすべての要素を参照するためには, 制御構造 for を次の形式で利用すればよい:
for ( 添字変数 in 連想配列 )
これは,bash の for-in と同様だ. たとえば,上の例の連想配列 color の要素をすべて出力するには, 次のようなアクションを記述すればよい.
for ( name in color ) { print name, color[name] }
これを実際に確かめたければ, 次のようなスクリプトを作成し,実行すればよい:
#!/usr/bin/awk -f BEGIN { color[...] = ...; # 連想配列の初期化 ... for ( ... ) { # 連想配列の出力 print ... } exit }
解答例は こちら.
投票データには, 米国大統領選挙における投票用紙に記入された候補者名が すべて記録されている.
なお,当然のことだが, 入力データが他のものに変わっても使えるスクリプトであること. つまり, 入力データ中の文字列定数("Trump" 等の候補者名)を スクリプトに書き込まないこと.
ヒント:
「○○氏の得票数は○票です」とか「○○氏に一票加算」という感じ. (上の例「color["..."] = "..."(○○の色は○です)」と比較しよう.)
なお,名前の部分には,入力したレコードのデータが入る.
$ grep 'clinton' vote.txt | wc # clinton の得票数を確認
...
上級者向け改良案:
実は,データファイル vote.txt を生成するためにも AWK が利用されました.
ご参考まで.