前回はフィルタコマンド「awk」の配列とfor制御構文について取り上げた。今回は、while制御構文について説明しよう。
while制御構文
前回紹介したawkスクリプトのなかでは、2つの処理でfor制御構文を使っていた。1つは、都道府県ごとに数を積算する処理だ。
for (j=1; j<=48; j++)
if ($2==n[j])
t[j] += 1
もう1つは、都道府県ごとに積算数を出力する処理(0件の場合は出力しない)である。
for (j=1; j<=48; j++)
if (0 != t[j])
printf("%s \t%d件\n",n[j],t[j])
これらをwhile制御構文で書き換えると、それぞれ次のようになる。
j=1
while (j<=48) {
if ($2==n[j])
t[j] += 1
++j
}
j=1
while (j<=48) {
if (0 != t[j])
printf("%s \t%d件\n",n[j],t[j])
++j
}
for制御構文もwhile制御構文も、書き方が少し違うだけで内容はほとんど同じだ。forやwhileといった制御構文を持つプログラミング言語は多いので、プログラマーならばよく見かけるコードだろう。
while制御構文に書き換えた場合、前回のawkスクリプトは次のようになる。
#!/bin/sh
key="$1"
awk '
BEGIN {
ken = "愛知県 青森県 秋田県 石川県 茨城県 岩手県 愛媛県 " \
"大分県 大阪府 岡山県 沖縄県 香川県 鹿児島県 神奈川県 岐阜県 " \
"京都府 熊本県 群馬県 高知県 埼玉県 佐賀県 滋賀県 静岡県 " \
"島根県 千葉県 東京都 徳島県 栃木県 鳥取県 富山県 長崎県 " \
"長野県 奈良県 新潟県 兵庫県 広島県 福井県 福岡県 福島県 " \
"北海道 三重県 宮城県 宮崎県 山形県 山口県 山梨県 和歌山県"
split(ken, n);
printf("====================================================\n")
printf("\t\t住所から郵便番号を検索\n")
printf("====================================================\n\n")
printf("検索キーワード: %s\n\n","'$key'")
printf("候補\t郵便番号 住所\n")
}
$2$3$4~/'$key'/ {
++i
printf("%03d\t%d (%s%s%s)\n",i,$1,$2,$3,$4)
j=1
while (j<=48) {
if ($2==n[j])
t[j] += 1
++j
}
}
END {
printf("\n県別集計\n")
j=1
while (j<=48) {
if (0 != t[j])
printf("%s \t%d件\n",n[j],t[j])
++j
}
printf("\n総候補数\t%d件\n",i)
}
' KEN_ALL_ROME.SSV
当然ながら、実行結果は前回と同じになる。特に難しいことはないと思うが、インデックスの開始が0ではなく1になることに留意しておいてほしい。
while制御構文とよく似たものに、do while制御構文がある。この構文では、最初に繰り返しの中身を実行し、最後に式を評価する。今回、while制御構文に書き換えた部分をさらにdo while制御構文に書き換えると次のようになる。
j=1
do {
if ($2==n[j])
t[j] += 1
++j
}
while (j<=48)
j=1
do {
if (0 != t[j])
printf("%s \t%d件\n",n[j],t[j])
++j
}
while (j<=48)
当然ながら、書き換えても実行結果は同じだ。
それ以外の制御構文としては、繰り返し構文から抜ける「break」と「continue」、処理を終了する「exit」、次のレコードに移る「next」などがある。この辺りを押さえておけば、awkのスクリプトは大体読めるようになるのではないかと思う。
自分で書く分には好きな制御構文だけ使っていればよいが、業務上、他人の書いたスクリプトを読まなければならないこともある。こうした記述方法があることは、覚えておくとよいだろう。
今回紹介したスクリプトからもわかるように、これまで取り上げてきた「grep」や「sed」などと比べると、awkのスクリプトにはかなりプログラミング言語感が強い。Linuxサーバの管理者にとって、スクリプトの中身に詳しくなることは必須ではないが、知っておくと何かと便利なはずだ。