我有这个 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
对于整数:
使用算术扩展: $((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) num= 1 num =2
bc 和 expr 期望每个数字和运算符作为单独的参数,因此空格很重要。他们不能处理像 3+ +4 这样的参数。 num=`expr $num1+ $num2`
使用 $(( ))
算术扩展。
num=$(( $num + $metab ))
请参阅 Chapter 13. Arithmetic Expansion 了解更多信息。
191.003 + 190
时,它在这里不起作用。
dc
或 bc
解决方案之一。
(())
之间是否必须使用 $
?好像没有
有一千零一种方法可以做到这一点。这是一个使用 dc
(支持无限精度算术的逆波兰桌面计算器)的例子:
dc <<<"$num1 $num2 + p"
但是,如果这对您来说太 bash-y(或可移植性问题),您可以说
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 本身不支持浮点数。如果您需要对浮点数求和,则需要使用外部工具(如 bc
或 dc
)。
在这种情况下,解决方案是
num=$(dc <<<"$num $metab + p")
将累积的可能浮点数添加到 num
。
在巴什,
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
我总是忘记语法,所以我来谷歌搜索,但后来我找不到我熟悉的那个:P。这对我来说是最干净的,也更符合我对其他语言的期望。
i=0
((i++))
echo $i;
我也很喜欢这种方法。杂乱无章:
count=$[count+1]
#!/bin/bash
read X
read Y
echo "$(($X+$Y))"
使用 shell 内置 let
。它类似于 (( expr ))
:
A=1
B=1
let "C = $A + $B"
echo $C # C == 2
另一种在 Bash 中兼容 POSIX 的可移植方式,可以将其定义为 .bashrc
中的函数,以方便所有算术运算符。
addNumbers () {
local IFS='+'
printf "%s\n" "$(( $* ))"
}
只需在命令行中调用它,
addNumbers 1 2 3 4 5 100
115
这个想法是使用 Input-Field-Separator(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
#!/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
不定期副业成功案例分享
num1
和num2
的变量存在并且具有整数值时,您是否尝试过这个?$((..))
算术评估是在 bash 中执行的。expr
作为单独的进程执行,因此会慢很多。在不支持算术评估的系统上使用后者(sh!=bash)$((…))
已由 POSIX 标准化,因此expr
的必要性应该越来越少。