blog

ソフトウェア開発|「数字を当てる」ゲームを書いてAwkを学ぶ

プログラミング言語には多くの共通点があります。新しい言語を学ぶ良い方法は、馴染みのあるプログラムを書くことです。この記事では、Awkを使って「数当て」プログラムを書くことで、身近な概念を示します。...

Oct 26, 2025 · 10 min. read
シェア

プログラミング言語には多くの共通点があります。新しい言語を学ぶ良い方法は、身近なプログラムを書くことです。この記事では、Awkを使って「数当て」プログラムを書くことで、身近な概念を示します。

新しいプログラミング言語を学ぶときは、ほとんどのプログラミング言語に共通していることに集中するのが一番です。

  • 変数 - 情報が格納される場所
  • 式 - 計算方法
  • ステートメント - プログラムの状態変化を表す方法。

これらの概念は、ほとんどのプログラミング言語の基礎となっています。

これらの概念を理解すれば、あとは自分で考え始めることができます。例えば、ほとんどの言語にはその設計でサポートされている「やり方」があり、それは言語によって大きく異なります。モジュール化、宣言型と命令型、オブジェクト指向、低レベルと高レベルの構文機能などです。多くのプログラマーは、プログラミングの「儀式」、すなわち問題に対処するためのシナリオを設定する作業に精通しています。Javaプログラミング言語には、その設計に由来する重要な儀式要件があると言われており、それはすべてのコードがクラスで定義されているということです。

しかし、基本的にプログラミング言語には共通点があります。あるプログラミング言語をマスターしたら、別の言語の基本を学び、その新しい言語の違いを味わうことから始めることができます。

そのための良い方法は、基本的なテスト手順を作成することです。そうすれば、これらの類似点から学び始めることができます。

作成するテストプログラムの1つに、「数字当て」プログラムがあります。コンピュータが1から100までの数字を選び、その数字を当てるように要求します。プログラムは、あなたが正解するまでループします。

数字当て」プログラムでは、プログラミング言語のいくつかの概念を練習します。

  • 変数
  • タイプ
  • 出力
  • 条件判定
  • ループ

これは新しいプログラミング言語を学ぶのに最適な実践的実験です。

:この記事は、Moshe Zadka氏による Julia このアプローチの使用法と、Jim Hall氏による Bash このアプローチの使用法を参考にしています。

awk プログラムでの数値の推測

数字当てゲーム」を実装するAwkプログラムを書いてみましょう。

Awkは動的に型付けされ、データ変換を指向するスクリプト言語であり、驚くほど優れた対話的使用のサポートを持っています。Awkは1970年代に登場し、もともとはUnixオペレーティングシステムの一部でした。Awkは1970年に登場し、もともとはUnixオペレーティングシステムの一部でした。Awkを知らなくてもスプレッドシートが好きなら、これは Awkを学びに行く サインです!

数字当てゲーム」のバージョンを書くことから、Awkを使い始めることができます。

  1.      1    BEGIN {
  2.      2        srand(42)
  3.      3        randomNumber = int(rand() * 100) + 1
  4.      4        print "random number is",randomNumber
  5.      5        printf "guess a number between 1 and 100 "
  6.      6    }
  7.      7    {
  8.      8        guess = int($0)
  9.      9        if (guess < randomNumber) {
  10.     10            printf "too low, try again:"
  11.     11        } else if (guess > randomNumber) {
  12.     12            printf "too high, try again:"
  13.     13        } else {
  14.     14            printf "that's right "
  15.     15            exit
  16.     16        }
  17.     17    }

Awkの制御構造がCやJavaに似ていますが、Pythonとは異なることがすぐにわかります。 if-then-elseやwhileのような文では、thenセクション、elseセクション、whileセクションは、単一の文または{と}で囲まれた文のセットを受け入れます。しかし、Awkには最初から理解しておかなければならない1つの大きな違いがあります:

設計上、Awkはデータパイプラインを中心に構築されています。

これはどういう意味ですか?ほとんどのAwkプログラムは、1行の入力を受け取り、そのデータで何かを行い、それを出力に書き出すコードの断片です。このような変換パイプラインの必要性を認識し、Awkはデフォルトですべての変換パイプラインを提供します。上のプログラムに関する基本的な質問から、このことを探ってみましょう:「コンソールからデータを読む」構造はどこにあるのでしょうか?

答えは「組み込み」です。具体的には、7行目から17行目までが、読み込まれた各行に対して何をすべきかをAwkに指示しています。この場合、1行目から6行目までが、何も読み込まれる前に実行されていることが簡単にわかります。

具体的には、1行目のBEGINキーワードは「パターン」で、この場合、データを読み込む前に、まずBEGINの後に続く{ ... の後にある { ... } を実行するように指示します。同様のキーワードであるENDは、このプログラムでは使用されていませんが、すべてのデータを読み込んだ後の処理をAwkに指示します。

7行目から17行目に戻ると、コードブロック{ ... }の断片に似たスニペットが作成されていることがわかります。 } フラグメントに似たスニペットが作成されていますが、その前にキーワードがありません。Awkがマッチさせる{は何もないので、この行を各入力行の受信に使用します。各入力行は、ユーザーが推測して入力します。

実行されるコードを見てみましょう。まず、入力を読み込むときに発生するプリアンブルがあります。

2行目で乱数発生器は42で初期化されます。 なぜ42なのでしょうか?3行目で1から100までの乱数を計算し、4行目でデバッグ用に乱数を出力します。5行目では、ユーザーに数字を推測してもらいます。この行ではprintではなくprintfを使用しており、C言語と同様、printfの第1引数は出力をフォーマットするためのテンプレートであることに注意してください。

ユーザーはプログラムが入力を要求していることを知っているので、コンソールに推測を入力することができます。前述したように、Awkはこの推測を7行目から17行目のコードに提供します。0ドルは入力レコード全体を表し、$1は入力レコードの最初のフィールド、$2は2番目のフィールドを表します。そうです、Awkはあらかじめ定義された区切り文字を使用して、入力行を各フィールドに分割します。9行目から15行目では、推測と乱数を比較し、適切な応答を表示します。推測が正しければ、15行目は入力行処理パイプラインから早期に終了します。

簡単なことです!

コード・スニペットが特定の入力行構成に反応してデータを処理するという、Awkプログラムの珍しい構造を考慮して、フィルタリング部分がどのように機能するか、別の構造を見てみましょう:

  1.      1    BEGIN {
  2.      2        srand(42)
  3.      3        randomNumber = int(rand() * 100) + 1
  4.      4        print "random number is",randomNumber
  5.      5        printf "guess a number between 1 and 100 "
  6.      6    }
  7.      7    int($0) < randomNumber {
  8.      8        printf "too low, try again: "
  9.      9    }
  10.     10    int($0) > randomNumber {
  11.     11        printf "too high, try again: "
  12.     12    }
  13.     13    int($0) == randomNumber {
  14.     14            printf "that's right "
  15.     15            exit
  16.     16        }

1~6行目は変更されていません。しかし、7~9行目は入力された整数値が乱数より小さいときに実行されるコード、10~12行目は入力された整数値が乱数より大きいときに実行されるコード、13~16行目は両者が等しいときに実行されるコードであることがわかります。

例えば、なぜ int($0) をダブルカウントするのでしょうか?確かに、問題を解決するには奇妙な方法です。しかし、これらのパターンは、正規表現やAwkでサポートされているその他の構文で使用することができるため、条件処理を分離するための素晴らしい方法です。

完全を期すために、これらのパターンを使って、一般的な計算と特定の環境だけに適用される計算を分けることができます。これが3番目のバージョンです:

  1.      1    BEGIN {
  2.      2        srand(42)
  3.      3        randomNumber = int(rand() * 100) + 1
  4.      4        print "random number is",randomNumber
  5.      5        printf "guess a number between 1 and 100 "
  6.      6    }
  7.      7    {
  8.      8        guess = int($0)
  9.      9    }
  10.     10    guess < randomNumber {
  11.     11        printf "too low, try again: "
  12.     12    }
  13.     13    guess > randomNumber {
  14.     14        printf "too high, try again: "
  15.     15    }
  16.     16    guess == randomNumber {
  17.     17        printf "that's right "
  18.     18        exit
  19.     19    }

学びたいことのリストに戻りましょう。

  • 入力データは文字列として入力されますが、必要に応じて数値に変換することができます。
  • 入力--Awkは、「データ変換パイプライン」によってデータを読み込むための入力を送信するだけです。
  • 出力 -- 出力への書き込みには、Awkのprint関数とprintf関数が使われています。
  • 条件判定 - Awkの if-then-else 、特定の入力行構成に対応する入力フィルタについて学びました。
  • ループを想像してみてください!Awkの「データ変換パイプライン」アプローチのおかげで、ループは必要ありません。Awkにend-of-fileシグナルを送ることで、パイプラインを早期に終了させることができます。

Awkがこれほど長く存続できた理由の1つは、Awkプログラムがコンパクトであることであり、コンパクトである理由の1つは、コンソールやファイルから読み込むすべてのフォーマットコードが必要ないことです。

次のプログラムを実行してみましょう:

  1. $ awk -f guess.awk
  2. random number is 25
  3. guess a number between 1 and 100: 50
  4. too high, try again: 30
  5. too high, try again: 10
  6. too low, try again: 25
  7. that's right

まとめ

Awkは非常に強力で、この「数字を当てる」ゲームは手始めに最適です。しかし、これでAwkの探求が終わるわけではありません。 みましょう。 GawkはAwkの拡張バージョンで、あなたのコンピュータでLinuxが動いていれば持っているかもしれません。あるいは、 開発者たちによる、 様々な情報を読むこともできます。

また、学んだことを記録するのに役立つ できます。

Read next