スクリプトの実行順序 (その 4) while 文

while 文の基本

while 文は, ある条件が成り立つ限り, 繰り返し, 同じ処理を実行する. 形式は:

while(条件式){
  処理
}

と, 次のような, do を使うものの2つがあ:

do{
  処理
}while(条件式)

scpt13_1.awk

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/usr/local/bin/gawk -f
# scpt13_1.awk

BEGIN{
    i = 1
    while(i <= 100){
	sum += i
	i++
    }
    print "1 から 10 までの合計は: " sum
}

scpt13_1.awk の実行結果は:

[cactus:~/code_awk/tuts]% ./scpt13_1.awk
1 から 10 までの合計は: 5050

もうひとつ, 学校でのテストの平均点を出す例を考えてみよう. 5 人の生徒が数学の練習問題をやる. ただし, 欠席した場合はテストを受けていないので, 全員のテストの回数にはぱらつきがある. 下の, scpt13_2.txt が成績表である. 最初に名前があり, 空白で点数が並んでいる.

scpt13_2.txt

scpt13_2.awk

#!/usr/local/bin/gawk -f
# scpt13_2.awk

BEGIN{
    print "氏名\t平均点" # 表の見出し
}

{
    sum = 0
    i = 2
    while(i <= NF){
	sum += $i
	i++
    }
    kaisu = NF - 1 # 試験の回数
    heikin = int(sum / kaisu)
    print $1 "\t" heikin
}

scpt13_2.awk の実行結果は:

[cactus:~/code_awk/tuts]% ./scpt13_2.awk data13_2.txt
氏名                      平均点
A君                      72
B君                      57
C君                      83
D君                      48
E君                      65

応用, getline と組み合わせて使う

getline 命令を使うと, 新たに一行を読み込ませることができる.

そのときには, 組み込み変数 FNR (ファイル単位での読み込み済み行数) や NR (awk を起動したときからの延べで計算あ読み込み行数) もインクリメント (一つ増えることだった) $1, $2, で表されるフィールドもセットされる. 例えば, たくさんのファイルの冒頭の部分だけを削除したいとか, ファイル中の特定の部分だけを特別に処理する場合にはこういうテクニックを使う.

html.txt

これは, タグ埋め込みテストです.
ここはまだ地の文です.
=EB=
ここから初めて,
いろいろ
あれこれ
もろもろ
ここまでを字下げします
=EE=
もとの地の文にもどりました.
地の文が続いています.
地の文の終わりです.

html.awk

#!/usr/local/bin/gawk -f
# html.awk

BEGIN{
    print "<HTML>"
    print "<HEAD>"
    print "<META http-equiv=content-type content=\"text/html; charset=utf-8\">"
    print "</HEAD>"
    print "<TITLE> テスト </TITLE>"
    print "<BODY>"
}

{
    if($0 ~ /^=EB=/){
	print "<BLOCKQUOTE>"
	getline
	do{
	    print $0 "<BR>"
	    getline
	}while($0 !~ /^=EE=/)
	print "</BLOCKQUOTE>"
    }
    else{ # =EB= でなければ, そのまま <BR> タグをつけて出力
	print $0 "<BR>"
    }
}

END{
    print "</BODY>" # 本文の終わりを示すタグ
    print "</HTML>" # HTML 文書の終わりを示すタグ
}

html.awk の実行結果は:

[cactus:~/code_awk/tuts]% ./html.awk html.txt
<HTML>
<HEAD>
<META http-equiv=content-type content="text/html; charset=utf-8">
</HEAD>
<TITLE> テスト </TITLE>
<BODY>
これは, タグ埋め込みテストです.<BR>
ここはまだ地の文です.<BR>
<BLOCKQUOTE>
ここから初めて,<BR>
いろいろ<BR>
あれこれ<BR>
もろもろ<BR>
ここまでを字下げします<BR>
</BLOCKQUOTE>
もとの地の文にもどりました.<BR>
地の文が続いています.<BR>
地の文の終わりです.<BR>
</BODY>
</HTML>
テスト これは, タグ埋め込みテストです.
ここはまだ地の文です.
ここから初めて,
いろいろ
あれこれ
もろもろ
ここまでを字下げします
もとの地の文にもどりました.
地の文が続いています.
地の文の終わりです.