如何在bash脚本中添加数字

我有这个bash脚本,我在第16行有一个问题。我怎么能把第15行的前面的结果,并将其添加到第16行的variables?

#!/bin/bash num=0 metab=0 for ((i=1; i<=2; i++)); do for j in `ls output-$i-*`; do echo "$j" metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15) num= $num + $metab (line16) done echo "$num" done 

对于整数

  • 使用算术扩展 : $((EXPR))

     num=$((num1 + num2)) num=$(($num1 + $num2)) # also works num=$((num1 + 2 + 3)) # ... num=$[num1+num2] # old, deprecated arithmetic expression syntax 
  • 使用外部expr实用程序。 请注意,这只适用于真正旧的系统。

     num=`expr $num1 + $num2` # whitespace for expr is important 

对于浮点

Bash不直接支持这个,但是有一些你可以使用的外部工具:

 num=$(awk "BEGIN {print $num1+$num2; exit}") num=$(python -c "print $num1+$num2") num=$(perl -e "print $num1+$num2") num=$(echo $num1 + $num2 | bc) # whitespace for echo is important 

您也可以使用科学记数法(例如: 2.5e+2


常见的陷阱

  • 当设置一个variables的时候,你不能在=两边有空格,否则会强制shell将第一个单词解释为要运行的应用程序的名字(例如: num=或者num

    num= 1 num =2

  • bcexpr期望每个数字和运算符作为一个单独的参数,所以空格是重要的。 他们不能像3+ +4那样处理参数。

    num=`expr $num1+ $num2`

使用$(( ))算术扩展。

 num=$(( $num + $metab )) 

有关更多信息,请参阅http://tldp.org/LDP/abs/html/arithexp.html

有一千种和一种方法来做到这一点。 这里有一个使用dc

 dc <<<"$num1 $num2 + p" 

但是,如果对你来说太麻烦了(或者便携性问题),你可以说

 echo $num1 $num2 + p | dc 

但也许你是那些认为RPN很诡异的人之一, 别担心! bc在这里为你:

 bc <<< "$num1 + $num2" echo $num1 + $num2 | bc 

也就是说,你可以对脚本进行一些无关的改进

 #!/bin/bash num=0 metab=0 for ((i=1; i<=2; i++)); do for j in output-$i-* ; do # for can glob directly, no need to ls echo "$j" # grep can read files, no need to use cat metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}') num=$(( $num + $metab )) done echo "$num" done 

编辑:

如BASH FAQ 022中所述 ,bash本身不支持浮点数。 如果需要对浮点数进行求和,则需要使用外部工具(如bcdc )。

在这种情况下,解决scheme将是

 num=$(dc <<<"$num $metab + p") 

将可能的浮点数累加到num

在bash中,

  num=5 x=6 (( num += x )) echo $num # ==> 11 

请注意,bash只能处理整数运算,所以如果你的awk命令返回一个分数,那么你将需要重新devise:这里是你的代码重写了一下,做awk中的所有math。

 num=0 for ((i=1; i<=2; i++)); do for j in output-$i-*; do echo "$j" num=$( awk -vn="$num" ' /EndBuffer/ {sum += $2} END {print n + (sum/120)} ' "$j" ) done echo "$num" done 

我也很喜欢这个方法,不那么混乱:

 count=$[count+1] 

我总是忘记语法,所以我来到谷歌,但是我从来没有find我熟悉的那个:P。 这对我来说是最清洁的,对于我在其他语言中所期望的更真实。

 i=0 ((i++)) echo $i; 
  #!/bin/bash read X read Y echo "$(($X+$Y))" 

您应该将元数据声明为整数,然后使用算术评估

 declare -i metab num ... num+=metab ... 

欲了解更多信息,请参阅https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html#Shell-Arithmetic

另一个便于POSIX方法是在bash做的,可以在.bashrc为所有算术运算符定义一个函数的方便。

 addNumbers () { local IFS='+' printf "%s\n" "$(( $* ))" } 

只是在命令行中调用它,

 addNumbers 1 2 3 4 5 100 115 

这个想法是使用input字段分隔符(IFS) ,这是一个用于扩展后分词的bash的特殊variables,可以将行分成单词。 该函数在本地将值更改为使用分词字符作为和运算符+

请记住, IFS在本地发生更改,不会对函数作用域之外的默认IFS行为生效。 摘自man bash页面,

shell将IFS的每个字符视为分隔符,并将其他扩展的结果拆分为这些字符上的单词。 如果IFS未设置,或者其值正好是默认值,那么以前扩展结果的开始和结束的序列,和,序列将被忽略,并且任何不在开始或结束的IFS字符序列用于分隔话。

"$(( $* ))"表示传递给被+分割的参数列表,随后使用printf函数输出和值。 该函数可以扩展为其他算术运算的范围。