我有这个bash脚本,我在第16行遇到一个问题。 我怎样才能把第15行的结果添加到第16行的变量中呢? 到第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
对于整数。
使用算术扩展: $((EXPR))
num=$((num1 + num2))
num=$(($num1 + $num2)) #也可以使用
num=$((num1 + 2 + 3)) # ...
num=$[num1+num2] # 旧的、被废弃的算术表达式语法
使用外部的expr
工具。请注意,只有在非常老的系统中才需要这样做。
num=`expr $num1 + $num2` # expr的空格很重要
对于浮动点。
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
)。
常见的陷阱。
当设置一个变量时,你不能在=
两边有空格,否则会迫使shell把第一个字解释为要运行的应用程序的名称(例如:num=
或num
)。
bc
和expr
希望每个数字和运算符都是一个单独的参数,所以空格很重要。它们不能处理像3+``+4
这样的参数。
有一千零一种方法可以做到这一点。这里有一个使用`dc'的方法。
dc <<<"$num1 $num2 + p"
但如果这对你来说太简单了(或者便携性问题),你可以说
echo $num1 $num2 + p | dc
但是,也许你是那种认为RPN很恶心、很奇怪的人;别担心!bc'是为你准备的。
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
EDIT:
正如BASH FAQ 022中所述,bash并不支持浮点数。如果你需要对浮点数进行求和,需要使用外部工具(如bc
或dc
)。
在这种情况下,解决方案是
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
#!/bin/bash
read X
read Y
echo "$(($X+$Y))"
另一种可移植的POSIX
兼容方式,可以在.bashrc
中定义为一个函数,方便所有的算术运算符。
addNumbers () {
local IFS='+'
printf "%s\n" "$(( $* ))"
}
并在命令行中调用它为。
addNumbers 1 2 3 4 5 100
115
其思路是使用输入-字段-分隔符(IFS),这是bash
中的一个特殊变量,用于扩展后的拆字,并将行拆成字。
该函数在本地改变值,使用拆字符作为和运算符+
。
请记住,IFS
是在本地改变的,不会对函数范围外的默认IFS
行为产生影响。
摘录自man bash
页面。
shell将IFS的每一个字符作为定界符,并将其他扩展的结果分割成这些字符上的字。 如果IFS没有设置,或者它的值正好是<空格><制表符><换行>,即默认值,那么<空格>、<制表符>和<换行>.的序列将被忽略。 在前面扩展结果的开头和结尾处的序列会被忽略,任何不在开头或结尾处的IFS字符序列都会被用来分隔单词。
"$(( $* ))"
表示传递过来的参数列表要被+
分割,之后用printf
函数输出和值。
该函数还可以进行扩展,以增加其他算术运算的范围。
#!/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