はじめに
シェル芸力を高めるにはさまざまな便利なコマンドを知り、そしてコマンドが持っている機能(オプション)を知り尽くすことが重要です。この記事ではあなたのシェル芸力を伸ばす num-utils について紹介します。
num-utils とは?
num-utils とはその名の通り、数値を扱うためのコマンドセットです。一つのコマンドではなく複数のコマンドの集まりです。行または行列に対しての数値処理を簡単に行うことができるコマンドセットです。num-utils の 公式サイトはこちらです。
num-utils を使用する場合の懸念点
num-utils はちょくちょく名前を見かけるコマンドですが一つ懸念点があり、現在メンテナンスが行われていないということです。最終更新日は 2004 年 11 月にリリースされたバージョン 0.5 です。2007 年には 1.0 をリリースするような告知があるのですが、実現されておらず、またメーリングリストなどでの活動も調べた限り見つかりませんでした。すでに実装されている機能は使えますが、一部バグが残っているので注意が必要です。
このバグのうち以下のバグは Debian / Ubuntu 系 Linux の公式パッケージ版では修正されていますが、Homebrew 版では修正されていません。
numprocess
Power operator (^) does not work - A typo was made on line 151. It should be$new_number = $new_number**$1
;
# Debian / Ubuntu 系 Linux では動く
echo 10 | numprocess '/^2/' # => 100
# macOS では動かない
echo 10 | numprocess '/^2/' # => 0
Debian / Ubuntu 系 Linux の公式パッケージ版では他にも修正が加えられているようなので以下のアドレスから確認することをおすすめします。
$ range /1..2/
Use of uninitialized value $prefix in concatenation (.) or string at /usr/local/bin/range line 142.
Use of uninitialized value $suffix in concatenation (.) or string at /usr/local/bin/range line 142.
Use of uninitialized value $prefix in concatenation (.) or string at /usr/local/bin/range line 140.
Use of uninitialized value $suffix in concatenation (.) or string at /usr/local/bin/range line 140.
1 2
コマンド名についての注意
num-utils は Debian / Ubuntu 系 Linux で公式にパッケージが提供されていますが、一部のコマンドでコマンド名が変更されています、おそらくその他のパッケージと名前が被ったまたは被りやすいと見なされて変更されたのでしょう。変更されたコマンド名はすべて頭に num
が追加されています(例 average
→ numaverage
)。以下の一覧で (num)
を付けているのが変更されたコマンド名です。
コマンド名 | 機能 |
---|---|
(num) average | 数列の平均値や最頻値や中央値を求める |
(num) bound | 数列から最小値や最大値を見つける |
(num) interval | 数列の中の数値の差を出力する |
(num) normalize | 数列を0から1(指定した範囲)の間で正規化する |
numgrep | 数列から任意の条件の数値の検索 |
numprocess | 数列に対して任意の計算を行う |
numsum | 数列や行列を縦や横に合計する |
(num) random | 数列からランダムな数値を一つ取り出す |
(num) range | 数列を生成する |
(num) round | 数列の四捨五入・切り上げ・切り下げを行う |
コマンド一覧
numsum - 数列や行列を縦や横に合計する
num-utils でおそらく最も便利なコマンドは numsum
コマンドではないかと思います。このコマンドは数列や行列を簡単に縦や横に合計する事ができるコマンドです。
$ seq 1 0.1 2 | numsum
16.5
$ numsum -c << 'HERE'
1 4 7
2 5 8
3 6 9
HERE
6 15 24
$ numsum -r << 'HERE'
1 4 7
2 5 8
3 6 9
HERE
12
15
18
numrange - 数列を生成する
numrange
コマンドは指定した表現から数列を生成するコマンドです。seq
コマンドに似ていますが、条件の異なる複数の数列を同時に生成することができます。数列は /開始値..終了値[i増分]/
の形で指定し、カンマで複数つなげて指定することができます。
$ numrange '/1..3,5,6..10i2/'
1 2 3 5 6 8 10
numrandom - 数列からランダムな数値を一つ取り出す
numrandom
コマンドは指定した表現の数列からランダムな値を一つ取り出して出力します。
$ numrandom '/1..100/'
43
numaverage - 数列の平均値や中央値などを求める
numaverage
コマンドは数列の平均値や最頻値や中央値を求めるコマンドです。
$ numrange -N '/1..3,1..5,2,6/' | numaverage
2.9
$ numrange -N '/1..3,1..5,2,6/' | numaverage -m
2
$ numrange -N '/1..3,1..5,2,6/' | numaverage -M # 中央に近い二つの値の上の値
3
$ numrange -N '/1..3,1..5,2,6/' | numaverage -M -l # 中央に近い二つの値の下の値
2
numprocess - 数列に対して任意の計算を行う
numprocess
コマンドは数列に対し引数で指定した計算を行うコマンドです。一般的な四則演算に加えて、累乗 ^
や sqrt
、sin
、cons
、円周率 pi
とネイピア数 e
の定数が利用可能です。
$ seq 3 | numprocess '/+5,*10/'
60
70
80
numinterval - 数列の中の数値の差を出力する
numinterval
コマンドは数列の数値の差を出力するコマンドです。
$ numrange -N '/2,4,16,256/' | numinterval
2
12
240
numbound - 数列から最小値や最大値を見つける
numbound
コマンドは数列の中の最大値と最小値を見つけ出すコマンドです。
$ numrange -N '/5,8,3,6/' | numbound
8
$ numrange -N '/5,8,3,6/' | numbound -l
3
numgrep - 数列から任意の条件の数値の検索
numgrep
コマンドは数列の中から条件にマッチした数値を出力するコマンドです。
$ seq 10 | numgrep '/3..5/'
3
4
5
$ seq 10 | numgrep '/m3/'
3
6
9
$ seq 10 | numgrep '/f6/'
1
2
3
6
numround - 数列の四捨五入・切り上げ・切り下げを行う
numround
コマンドは数列を四捨五入、切り上げ、切り下げを行うコマンドです。
$ numrange -N '/10.4,10.5,10.6,-10.5/' | numround
10
11
11
-11
$ numrange -N '/10.4,10.5,10.6,-10.5/' | numround -c
11
11
11
-10
$ numrange -N '/10.4,10.5,10.6,-10.5/' | numround -f
10
10
10
-11
numnormalize - 数列の合計値を1として値を正規化する
numnormalize
コマンドは数列の合計を 1 (100%) として、それぞれの値を 0 から 1 の間で正規化するコマンドです。
$ seq 3 | numnormalize
0.166666666666667 👈 1/6
0.333333333333333 👈 2/6
0.5 👈 3/6
さいごに
num-utils を使うとちょっとした数値の計算が簡単に行うことができます。特に行や行列の合計が簡単にできるのは便利で、awk を使うまでもないというようなときに使うことができます。更新が行われておらずバグが残っているのが少々気がかりなので、誰か後を引き継いで修正したり Rust 実装版などを作ってくれないかなー?なんて思っています。