减去具有浮点小数的2个数组值

时间:2015-12-23 01:25:02

标签: bash unix

我正在读取一个包含多列的文件,并将该文件的两列转换为两个不同的数组。现在基于一个条件,我需要得到从数组中检索的2个值之间的差异。所以我的代码看起来像这样 -

if [ condition ]; then
VAL = (( ${local[$x]} - ${local[$y]} ))
fi

问题是,虽然我能够回显并看到值${local[$x]}${local[$y]},但减法操作会给我一个语法错误。我理解它失败了,因为当前在数组中保存的值涉及浮点十进制值 - 如3456712.126758,并且赋值会引发小数部分的错误。我理解算术运算不是bash shell的强项,因为浮点数被认为是字符串因此是问题。

请您帮忙获得正确的格式吗? 我应该做这样的事吗

VAL= awk '{ print ${local[$x]} - ${local[$y]} }'

VAL=echo ${local[$x]} - ${local[$y]} | bc -l

我确定上面的语法是错误的,请使用语法帮助,我需要将分配的结果分配给字段VAL

2 个答案:

答案 0 :(得分:1)

使用awk:

awk -v a=${a} -v b=${b} 'BEGIN{print a - b}'

用bc:

echo "${a} - ${b}" | bc -l

另请参阅其他选项here

答案 1 :(得分:1)

不仅浮点,而且间距也会导致语法错误。 Bash变量赋值必须没有空格,如val=x,而不是val = x

大写变量名称是为环境变量保留的,建议使用小写代替您自己的变量。 (哦,local 也是一个保留字。)

您的作业无法使用适当的间距:arithmetic expression

var=(( ${vals[$x]} - ${vals[$y]} ))   # syntax error near unexpected token `('

只是评估其内容,但没有返回任何内容。您可以使用=之后的部分作为条件。要使其返回某些内容,您需要arithmetic expansion(请注意额外的$):

var=$(( ${vals[$x]} - ${vals[$y]} ))    # works for integers
    ^

在算术环境中,您甚至不需要在变量前加$

var=$(( vals[x] - vals[y] ))

同样适用。例外:在associative arrays中,您仍需要为索引执行此操作:

$(( vals[$x] ))

最后,正如您所注意到的,这一切都不适用于浮点数。您也可以使用here string并避免产生子shell,而不是管道bc

$ vals=(1.1 2.2)
$ x=0
$ y=1
$ echo $(( local[x] - local[y] ))    # No '$' needed for variable expansion
bash: 1.1: syntax error: invalid arithmetic operator (error token is ".1")  # But :(
$ bc -l <<< "local[x] - local[y]"   # Requires '$' - these expand to nothing
0
$ bc -l <<< "${local[x]} - ${local[y]}"   # Works!
-1.1