如何在bash脚本中添加数字

Nic*_*ick 523 bash mathematical-expressions integer-arithmetic

我有这个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
Run Code Online (Sandbox Code Playgroud)

Kar*_*ath 916

对于整数:


对于浮点数:

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
Run Code Online (Sandbox Code Playgroud)

你也可以用科学记数法(如:2.5e+2)


常见的陷阱:

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

    num= 1 num =2

  • bcexpr期望每个数字和运算符作为一个单独的参数,因此空格很重要.他们无法处理像这样的论点3+ +4.

    num=`expr $num1+ $num2`

  • 由于`$((...))`是由POSIX标准化的,因此`expr`是必要的,这种情况越来越少见. (4认同)
  • 是的,这是一个问题:)注意:`$((..))`算术评估在bash中执行.`expr`作为一个单独的进程执行,所以它会慢得多.在不支持arithemtic评估的系统上使用后者(sh!= bash) (2认同)

Ste*_*ice 90

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

num=$(( $num + $metab ))
Run Code Online (Sandbox Code Playgroud)

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

  • 不适用于CentOS和RedHat (3认同)
  • 奇怪的。当我尝试计算“191.003 + 190”时,它在这里不起作用。 (2认同)
  • @Sigur我相信这是因为bash本身不支持浮点数学。即这个方法,虽然很好,但只适用于整数。尝试使用“dc”或“bc”解决方案之一。 (2认同)

Sor*_*gal 27

有一千零一种方法可以做到这一点.这是一个使用dc:

dc <<<"$num1 $num2 + p"
Run Code Online (Sandbox Code Playgroud)

但是,如果这对你来说太过苛刻(或可移植性问题)你可以说

echo $num1 $num2 + p | dc
Run Code Online (Sandbox Code Playgroud)

但也许你是那些认为RPN狡猾而怪异的人之一; 别担心!bc在这里为您服务:

bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc
Run Code Online (Sandbox Code Playgroud)

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

#!/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
Run Code Online (Sandbox Code Playgroud)

编辑:

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

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

num=$(dc <<<"$num $metab + p")
Run Code Online (Sandbox Code Playgroud)

添加累积可能的浮点数num.


gle*_*man 22

在bash,

 num=5
 x=6
 (( num += x ))
 echo $num   # ==> 11
Run Code Online (Sandbox Code Playgroud)

请注意,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
Run Code Online (Sandbox Code Playgroud)


小智 19

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

i=0
((i++))

echo $i;
Run Code Online (Sandbox Code Playgroud)


小智 15

我也非常喜欢这种方法,不那么杂乱:

count=$[count+1]
Run Code Online (Sandbox Code Playgroud)

  • 不那么混乱,但已弃用. (4认同)
  • 顺便问一下,为什么这会起作用?我们怎么称呼这个?我找不到有关这些的文档。 (2认同)

小智 15

 #!/bin/bash
read X
read Y
echo "$(($X+$Y))"
Run Code Online (Sandbox Code Playgroud)


小智 9

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

declare -i metab num
...
num+=metab
...
Run Code Online (Sandbox Code Playgroud)

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


cha*_*les 8

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

A=1
B=1
let "C = $A + $B"
echo $C # C == 2
Run Code Online (Sandbox Code Playgroud)

来源:Bash let 内置命令


Ini*_*ian 7

在中执行的另一种可移植的POSIX兼容方式bash.bashrc对于所有方便的算术运算符,都可以将其定义为功能。

addNumbers () {
    local IFS='+'
    printf "%s\n" "$(( $* ))"
}
Run Code Online (Sandbox Code Playgroud)

然后在命令行中以

addNumbers 1 2 3 4 5 100
115
Run Code Online (Sandbox Code Playgroud)

这个想法是使用Input-Field-Separator(IFS),这是一个特殊变量,bash用于扩展后的单词拆分以及将行拆分为单词。该函数在本地更改值,以使用分词字符作为求和运算符+

记住IFS局部改变,并没有采用默认效果IFS的功能范围之外的行为。man bash页面摘录,

外壳将IFS的每个字符视为定界符,并将其他扩展的结果拆分为这些字符上的单词。如果未设置IFS,或者其值正好是默认值,则将忽略,以及上一个扩展结果的开头和结尾处的序列,并且任何不在开头或结尾处的IFS字符序列都用于定界话。

"$(( $* ))"表示传递给被分割参数列表+和后来的总和值是使用输出printf功能。该功能可以扩展以增加其他算术运算的范围。


Ude*_*esh 6

#!/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
Run Code Online (Sandbox Code Playgroud)