Shell之數學計算


本博客已經遷往http://www.kemaswill.com/, 博客園這邊也會繼續更新, 歡迎關注~

 

數學計算是Shell中比較常用的一種操作,  但是因為shell中所有的變量都默認為字符串, 這就使得在shell中進行數學計算比較復雜, 以下直覺上貌似正確的方法是不對的:

#第一種錯誤方法
$ var=1+1
#第二種錯誤方法
$ var=1
$ var=$var+1

以上兩種方法的輸出結果都是1+1 , 而不是我們期望的2 .

在shell中進行數學計算可以通過以下方法來進行:

1. declare

我們可以聲明一個變量的類型, 比如聲明變量n為整數declare -i n

$ n=6/3
$ echo $n
6/3
$ declare -i n
$ n=6/3
$ echo $n
2

2. expr

可以使用expr命令, 注意其對空格比較敏感, 需要在+號附近都有空格

$ z=5
$ z=`expr $z+1`   ---- Need spaces around + sign.
$ echo $z
5+1
$ z=`expr $z + 1`
$ echo $z
6

3. let

let也是對空格敏感的, 不過與expr相反, 其+號附近不能有空格(略難記啊...:(), let語句中還可以省略$符號

$ let z=5
$ echo $z
5
$ let z=$z+1
$ echo $z
6
$ let z=$z + 1     # --- Spaces around + sign are bad with let
-bash: let: +: syntax error: operand expected (error token is "+")

$let z=z+1         # --- look Mom, no $ to read a variable.
$echo $z
7

let的另一種形式是用雙括號把數學計算的語句包圍起來, 而且對空格比較寬容, 在+號附近有無空格都可以

$ ((e=5))
$ echo $e
5
$ (( e = e + 3 ))
$ echo $e
8
$ (( e=e+4 ))  # -- spaces or no spaces, it doesn't matter
$ echo $e
12

4. bc

let不支持浮點數操作, 這時候需要用到bc

$let r=3.5
-bash: let: r=3.5: syntax error in expression (error token is ".5")
$(( r = 3.5 ))
-bash: ((: r = 3.5 : syntax error in expression (error token is ".5 ")

bc既可以以交互的方式執行, 也可以作為shell的一個命令.

交互方式:

$ bc
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
3 + 2
5
obase=2
12
1100
<cntrl-d>

作為shell的一個命令:

$r=3.5
$s=`echo "$r + 2.2" | bc`
$echo $s
5.7

$ z = `echo $z + 1 | bc`
-bash: z: command not found
                # =號附近不能有空格, 這是shell的語法限制的, 不是bc

$ z=`echo "$z + 1" | bc`
$ echo $z
8
$ z=`echo "$z+1" | bc`  #bc中對空格不敏感
$ echo $z
9

5. 其他

網上有人總結了一個非常全的各種shell中數學計算的方法[2]:

$ echo $((20.0/7))
$ zcalc
$ bc <<< 20+5/2
$ bc <<< 'scale=4;20+5/2'
$ expr 20 + 5
$ calc 2 + 4
$ node -pe 20+5/2  # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
$ echo 20 5 2 / + p | dc 
$ echo 4 k 20 5 2 / + p | dc 
$ perl -E "say 20+5/2"
$ python -c "print 20+5/2"
$ python -c "print 20+5/2.0"
$ clisp -x "(+ 2 2)"
$ lua -e "print(20+5/2)"
$ php -r 'echo 20+5/2;'
$ ruby -e 'p 20+5/2'
$ ruby -e 'p 20+5/2.0'
$ guile -c '(display (+ 20 (/ 5 2)))'
$ guile -c '(display (+ 20 (/ 5 2.0)))'
$ slsh -e 'printf("%f",20+5/2)'
$ slsh -e 'printf("%f",20+5/2.0)'
$ tclsh <<< 'puts [expr 20+5/2]'
$ tclsh <<< 'puts [expr 20+5/2.0]'
$ sqlite3 <<< 'select 20+5/2;'
$ sqlite3 <<< 'select 20+5/2.0;'
$ echo 'select 1 + 1;' | sqlite3 
$ psql -tAc 'select 1+1
$ R -q -e 'print(sd(rnorm(1000)))'
$ r -e 'cat(pi^2, "\n")'
$ r -e 'print(sum(1:100))'
$ smjs
$ jspl

參考文獻:

[1]. Math in Shell Scripts

[2]. How to do integer & float calculations, in bash or other languages/frameworks?

[3]. Shell中數學計算總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM