AWK Shell

AWKコマンド練習問題:5 数値演算をやってみよう

久しぶりのAWKシリーズ第5回目、今回はAWKで数値演算を試してみましょう。

四則演算

AWKでは一般的な四則演算の数式をそのまま記述することで、計算結果を出力することが可能です。

例えば、((198 * 256) + (214 * 319)) * 18 - 931を計算してみると2140241となりますが、実際にこの数式をawkコマンドで計算してみると

結果が正しく出力されました。

数式はコマンドの引数として計算することも可能です。

こちらをcalc.shとして保存して

このスクリプトに数式を引数として実行すると

ご覧のように計算結果が出力されます。

数値演算関数

AWKでは三角関数、指数や対数の数値演算系の関数が用意されています。

これらを用いればもっと複雑な計算もできそうです。

三角関数

正弦を表すsin()関数と余弦を表すcos()関数があります。ただし、正接を表す(tan)関数は存在しません。正接を導き出す際にはsin を cos で割ります

また、sin()cos()に渡す引数は角度(deg)ではなくラジアン(rad)です。

角度からラジアンへの変換式はrad = deg * π / 180です。

このπは属に3.14という決め打ちの値になりがちですが、atan2()関数を用いて計算することが可能です。

atan2の細かい部分は割愛しますが、ここではatan2(0, -0) = πになることがポイントです。

これを使えば任意の角度のラジアンを求めることができます。

例えば、45度では

という風にrad = deg * π / 180の式に当てはめるだけです。

指数、対数

ネイピア数eを底とする対数をlog()関数で表現でき、eの指数関数はexp()として表現できます。

複雑は数式に当てはめるところがあれば使えるかもです。(多分使わないでしょう・・

乱数

rand()関数を使って0 ~ 1 (0 <= rand < 1)までの乱数を生成できます。・・・が、何度実行しても同じ値になるため、事前にsrand()関数で乱数の種となるものを初期化する必要があります。

1から100までの乱数を出力したい場合はこのように表現します。

int()関数は少数のうち、整数部分を抜き出すのに使えます。

練習問題

そんなこんなで、数値計算を使った問題を解いてみましょう。

 

問題1

以下の教育テストのCSVデータ(test.csv)を用います。

  1. 全員の合計点を"名前 合計点"のフォーマット(スペース区切りで良い)で出力してください。
  2. sortコマンドを利用して合計点が降順にして1の結果を出力してください。
  3. 平均点(整数)を"名前 平均点"のフォーマットにし、sortコマンドを利用して平均点の降順で出力してください。

問題2

以下の辺a, 辺bおよびaとbの角度を表す三角形のCSVデータ(sankaku.csv)を用います。

  1. atan2()関数を用いて角度(deg)をラジアン(rad)に変換して出力してください。* 角度とラジアンの変換関数はrad = deg * π / 180である。
  2. それぞれの三角形の面積を出力してください。* 三角形の面積(S)はS =  (a* b * sin(θ)) /2で求められる。

問題3 (難)

次の大アルカナの表(arcana.txt)を用いて以下の仕様をみたすタロット占いを行うスクリプト(arcana.sh)を作成してください。

 

  • 実行に用いる引数は無し(ファイル名のみで実行)
  • カード番号(0から21)を表す乱数r1と正位置(1~5)、逆位置(6~10)を表す乱数r2を用いる
  • 出力形式はアルカナ名  位置で表す。例:JUSTICE  POSITIVE

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

できましたかね・・それでは解答例はこちら!

問題1

1 全員の合計点を"名前 合計点"のフォーマット(スペース区切りで良い)で出力してください。

CSVを読み取っているのでフィールドパターンはカンマ(,)で2行目から出力するための条件としてNR>=2をつけましょう。

2 sortコマンドを利用して合計点が降順にして1の結果を出力してください。

1で出力した結果をパイプで繋いでsortコマンドに渡してやればOKです。

-k 列番号でソートしたい列を指定、-rで昇順の反対である降順を指定できます。

3 平均点(整数)を"名前 平均点"のフォーマットにし、sortコマンドを利用して平均点の降順で出力してください。

2の計算式の部分を5で割ってやればOKです。

問題2

1 atan2()関数を用いて角度(deg)をラジアン(rad)に変換して出力してください。

計算式に3列目を割り当てるだけですね。

それぞれの三角形の面積を出力してください。

1の計算結果をradという変数に格納して、計算式に当てはめれば求められます。

問題3

シェルスクリプトの知識と、AWKでの条件分岐の知識など必要なのでググりながらやりましょう。

r1に1~22までの乱数(アルカナの番号は0 ~ 21ですが、arcana.txtの該当する行を抽出するため)、r2に1~10までの乱数を入れます。

変数arcanaaracana.txtを読み込んでr1の行番号になったものを出力して格納し、

変数positionr2が1 ~ 5なら"POSITIVE"、6 ~ 10なら"NEGATIVE"を格納し、

最後にそれらを"アルカナ名 位置"で出力すれば完成です。

「シェル芸」に効く!AWK処方箋
コマンドであり軽量言語(LL)の元祖でもあって、
シェルでのテキストデータ処理には便利で手放せない
「AWK」の魅力と書き方、シェルコマンドと組み合わせた
テクニック(シェル芸)を解説!

-AWK, Shell

© 2023 Shiro's secret base