(1) 1 行入力する (暗黙の getline) | ||||
(2) 現在行が「ア」の行かチェック | ||||
(3) 「ア」ならば、その行を保存して | ||||
(4) その行が「イ」であるかチェック | ||||
(5) 「イ」ならば、次の行を取得し それが「エ」であるかチェック | ||||
(6) 「エ」ならば、保存したものに `;' をつけて出力する | ||||
(7) 「エ」でなければ、(2) に戻る | ||||
(8) (4) が「イ」でなければ「オ」であるかチェック | ||||
(9) 「オ」ならば、(1) に戻る | ||||
(10) 「オ」でなければ、次の行を取得し それが「ウ」であるかチェック | ||||
(11) 「ウ」ならば、その行を保存し (4) に戻る | ||||
(12) 「ウ」でなければ、(2) に戻る | ||||
(13) (2) が「ア」でなければ、(1) に戻る |
これを AWK の疑似コード (おおまかなコード) として書いてみると、 例えば次のようになります。
{ while(1){ if(!「ア」) next (リセットして保存) while(1){ if(「イ」){ getline if(「エ」){ (出力); next } else break } else if(「オ」) next else{ getline if(!「ウ」) break (保存) } } } }このコードでポイントとなるのは、2 つの while 文です。 ``while(1)'' は、C 言語でもよく使われる手法ですが、 条件判断が常に真 (つまり 1) であるループなので、 無限ループを作っていることになります。
「ア」の条件判断をこの while ループの外に出して先頭の行に書いてしまうと、 「ア」の判断の前には必ず行の取得 (暗黙の getline) が 行われることになってしまい、(7) や (12) を実現できません。 よって、それを while(1) で囲むことで 行を取得せずに「ア」の判断部分に戻れるようにしていて、 行を取得してから「ア」の判断をしたい場合は next を使うようにして その while 文から抜け出すようにしています。
2 つ目の while(1) 文は、「ウ」のループ構造の実現のためです。 フローチャートを見ればわかりますが、 「ウ」で保存した後は次の行や「ア」の上に戻るのではなく、 「イ」の上に戻りますので、この流れがひとつのループ構造になっています。 よって、そこをなんらかのループとして書く必要があるわけです。 ここでは、「ウ」でない場合にこの 2 つ目の while ループから抜けて 「ア」の上に戻る、つまり (12) を実現するために break 文を使って 内側の while ループから抜け出しています。
「イ」の後の処理である (5),(6),(7) も while ループの中に書きましたので、 (7) では break 文で内側のループから抜けるようにしていますが、 「イ」だった場合にまず break して内側の while ループから抜け、 その外でその後の処理 (5),(6),(7) の処理を書く、という手もあります。 ただし、その場合その部分は、(12) で break したのではないことを 区別するためのコードを書く必要があります。