如何在Bash脚本中添加数字?

我有这个Bash脚本,我在第16行遇到了一个问题。 我如何获取第15行的前一个结果并添加 第16行的变量?

#!/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
1197931 次浏览

对于整数

  • 使用算术展开$((EXPR))

    num=$((num1 + num2))
    num=$(($num1 + $num2))       # Also works
    num=$((num1 + 2 + 3))        # ...
    num=$[num1+num2]             # Old, deprecated arithmetic expression syntax
    
  • Using the external expr utility. Note that this is only needed for really old systems.

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

For floating point:

Bash doesn't directly support this, but there are a couple of external tools you can use:

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)。


常见的陷阱

  • 设置变量时,不能在=的两边都有空格,否则会强制shell将第一个单词解释为要运行的应用程序的名称(例如,num=num

    num= 1num =2

  • bcexpr期望每个数字和运算符作为单独的参数,因此空格很重要。它们不能处理像3++4这样的参数。

    num=`expr $num1+ $num2`

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

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

有关更多信息,请参阅第十三章算术展开

有一千零一种方法可以做到这一点。这是一个使用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常见问题022中所述,Bash本身不支持浮点数。如果您需要对浮点数求和,则需要使用外部工具(如bcdc)。

在这种情况下,解决方案将是

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

将累积可能浮点数添加到num中。

在Bash

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

请注意,Bash只能处理整数算术,因此如果您的AWK命令返回分数,那么您需要重新设计:这是您的代码重写了一点,以便在AWK中执行所有数学运算。

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

我也很喜欢这个方法。有更少的混乱:

count=$[count+1]

我总是忘记语法,所以我来谷歌搜索,但后来我再也找不到我熟悉的那个:P.这对我来说是最干净的,更符合我在其他语言中的期望。

i=0
((i++))


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

另一种可移植的POSIX兼容方式在Bash中完成,它可以定义为.bashrc中的一个函数,方便所有算术运算符。

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

并在命令行中调用它,

addNumbers 1 2 3 4 5 100
115

这个想法是使用输入-字段-分隔符(IF S),这是Bash中的一个特殊变量,用于在展开后拆分单词并将行拆分为单词。该函数在本地更改值以使用拆分单词的字符作为和运算符+

记住IFS在本地更改,没有是否对函数范围之外的默认IFS行为生效。man bash页面的摘录,

shell将IFS的每个字符视为分隔符,并将其他扩展的结果拆分为这些字符上的单词。如果IFS未设置,或者其值正好为默认值,则忽略前面扩展结果的开头和结尾的、、和序列,并且任何不在开头或结尾的IFS字符序列都用于分隔单词。

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

您应该将metab声明为整数,然后使用算术求值

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

有关详细信息,请参阅6.5 Shell算术

#!/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)
let num=num+metab (line 16)
done
echo "$num"
done

使用shell内置的let。它类似于(( expr ))

A=1
B=1
let "C = $A + $B"
echo $C # C == 2

图片来源:Bash让内置命令

#!/usr/bin/bash


#integer numbers
#===============#


num1=30
num2=5


echo $(( num1 + num2 ))
echo $(( num1-num2 ))
echo $(( num1*num2 ))
echo $(( num1/num2 ))
echo $(( num1%num2 ))


read -p "Enter first number : " a
read -p "Enter second number : " b
# we can store the result
result=$(( a+b ))
echo sum of $a \& $b is $result # \ is used to espace &




#decimal numbers
#bash only support integers so we have to delegate to a tool such as bc
#==============#


num2=3.4
num1=534.3


echo $num1+$num2 | bc
echo $num1-$num2 | bc
echo $num1*$num2 |bc
echo "scale=20;$num1/$num2" | bc
echo $num1%$num2 | bc


# we can store the result
#result=$( ( echo $num1+$num2 ) | bc )
result=$( echo $num1+$num2 | bc )
echo result is $result


##Bonus##
#Calling built in methods of bc


num=27


echo "scale=2;sqrt($num)" | bc -l # bc provides support for calculating square root


echo "scale=2;$num^3" | bc -l # calculate power