0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

bash で数値計算しようとして罠に

Posted at

bash で数値計算しようとして罠に

bash で数値計算する方法

Bash で数値計算しようとすると

NUM=1
RESULT=$(expr $NUM + 1)
echo $RESULT

これで計算できます。Bashの場合はもっと良い方法として、

NUM=1
RESULT=$(($NUM + 1))
echo $RESULT

この書き方もあります。どうやらこっちの方が早いらしいです。

ある時、 exprを利用していたものを $(( ... )) の書き方に変更しました。
すると、把握していなかった expr$(( ... )) の動きの違いにはまり混乱しました。

ある日…、01_hoge.tgz みたいなファイル名があった場合に、02_hoge.tgz みたいな番号を計算して出そうとしていました。

最初次のように書いていました。

NUM=$(ls *_hoge.tgz | tail -n1 | cut -d_ -f1)
RESULT=$(expr $NUM + 1 )
echo $RESULT

これで動いていました。そして、リファクタリングをして、

NUM=$(ls *_hoge.tgz | tail -n1 | cut -d_ -f1)
RESULT=$(( $NUM + 1 ))
echo $RESULT

このように書き換えました。これも動きました。最初は。
しばらくして、番号が、08_hoge.tgz が表れた時…

value too great for base (error token is "08")

とエラーが起きました…。

$(( ... )) は 0xFF(16進数) や 071(8進数)といった表記を解釈するようです。
対して expr はあくまで10進数の数値であることを前提にしているようです。

今回は、2桁に揃えるために0で埋めていたために、8進数として解釈され、存在しない 8 という数字でエラーが起きました。最初うまく動いていただけに、しばらく気づけませんでした…。

結論、今回は意図して、expr を使うのが良いということがわかりました。

最後に

$(( ... ))0xFF010といった表記を解釈して、exprはあくまで10進数として解釈するという話は忘れないようにしましょうという話でした。

特に、01, 02, 03, ... みたいな連番を作りたい場合は、特に気を付けましょう。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?