2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シェル芸Advent Calendar 2023

Day 13

あなたのシェル芸力を伸ばす num-utils のススメ ~ 数値を縦横に合計したい?numsumでできるよ!

Last updated at Posted at 2023-12-16

はじめに

シェル芸力を高めるにはさまざまな便利なコマンドを知り、そしてコマンドが持っている機能(オプション)を知り尽くすことが重要です。この記事ではあなたのシェル芸力を伸ばす 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 の公式パッケージ版では他にも修正が加えられているようなので以下のアドレスから確認することをおすすめします。

Homebrew 版で発生するその他のバグ(警告が出る)
$ 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 が追加されています(例 averagenumaverage)。以下の一覧で (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増分]/ の形で指定し、カンマで複数つなげて指定することができます。

1から3、5、6から10の偶数を出力
$ 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
中央値(データの数が偶数個の場合は -l で下の値を取得できる)
$ 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 コマンドは数列に対し引数で指定した計算を行うコマンドです。一般的な四則演算に加えて、累乗 ^sqrtsincons、円周率 pi とネイピア数 e の定数が利用可能です。

1から3の数列に5を加えて10倍する
$ 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 コマンドは数列の中から条件にマッチした数値を出力するコマンドです。

3から5の範囲を出力
$ seq 10 | numgrep '/3..5/'
3
4
5
3の倍数を出力
$ seq 10 | numgrep '/m3/'
3
6
9
12を割り切れる数を出力
$ 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 の間で正規化するコマンドです。

1 + 2 + 3 = 6 を 1 として考えて正規化を行う
$ seq 3 | numnormalize
0.166666666666667     👈 1/6
0.333333333333333     👈 2/6
0.5                   👈 3/6

さいごに

num-utils を使うとちょっとした数値の計算が簡単に行うことができます。特に行や行列の合計が簡単にできるのは便利で、awk を使うまでもないというようなときに使うことができます。更新が行われておらずバグが残っているのが少々気がかりなので、誰か後を引き継いで修正したり Rust 実装版などを作ってくれないかなー?なんて思っています。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?