二重括弧による計算
Bashなどでは、
1 2 3 4 |
|
みたいな感じで二重括弧の中で数式を書くことで計算することが出来ます。
実際には数字を代入したりすることも含めていろいろな事ができます。
Arithmetic Expansion (Bash Reference Manual)
0Xな数字を二重括弧で計算する
ファイル名などで、数字をインクリメントして名前をつけていきたい、 10個以上になることもあるので10の位をゼロ埋めした状態にしたい、ということがある場合。
01, 02, 03….
みたいな感じにするために
1 2 3 4 5 6 7 8 9 |
|
のようにしていくと、
1 2 3 |
|
といった感じのファイル名が出来上がります。
$(())
の中で01
とかでも足し算で2
とかにしてくれるので一見これで良いような。
n
を分けて、ファイル名にする方だけでprintf
して02
のような形も出来ますし、
この場合はそれでもあまり変わらないのですが、
場合によっては直接suffixとして変更していったほうがわかりやすいこともあるかと思います。
問題はn
が8を超えた時、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
とすると、最後の足し算のところで、
1
|
|
といったエラーが起こります。
これはn
が08
の時ですが、01 + 1
というのは実は普通の1 + 1
ではなくて、
前者を8進数の1
として解釈して10進数の1
と足して10進数での2になってそれを表示しています。
01
~07
は10進数でも1
~7
になるので小さい数字だけでチェックすると問題を見落とします。
8進数なので9
という数は存在せずエラーになります。
二重括弧での数字
他の言語とかでも0
が0
が先頭なら8進数、0x
なら16進数、
また、0b
だと2進数とするものがあります。
Bashなどの(())
の計算では、0
から始まるものは8進数、0x
なら16進数として扱われます。
1 2 3 4 |
|
加えて、64までであれば自由な数字で進数を作ることが出来ます。
ベースとなる数字を#
の前に書けば、
1 2 3 4 5 6 |
|
といった感じに64進数まで使えます。
Shell Arithmetic (Bash Reference Manual)
64までは、0
~9
の数字、a
~z
で10
~35
、A
~Z
で36
~61
、残り@
、_
が62
、63
を表します。
1 2 3 4 5 6 |
|
これらで使われる文字が表す数字がベースの数字以上になるとエラーになります。
1 2 |
|
exprでは単に無視する
シェルスクリプトで簡単に計算しようと思うとexpr
というコマンドがありますが、
こちらでは08
も8
も同じように0
がないものとして扱われます。
1 2 |
|
単に左にある0を無視するだけなので、0xa
のような16進数のようなものは使えません。
1 2 |
|
この辺ちゃんとそれぞれ分かっていれば良いのですが、 書き換えとかで同じようにしてしまうと間違えてしまうかも。
このexpr
ですが現在では
ShellCheck
とかで
1
|
|
といった忠告を出すようになっていて二重括弧による計算が推奨されています。
ということで
1 2 3 4 5 6 7 8 9 |
|
のように素直に数字は数字でインクリメントしてファイル名などに埋める時に0埋めするべきだと。