如何比较bash / awk中的两个十进制数?

时间:2022-12-16 12:06:24

I am trying to compare two decimal values but I am getting errors. I used

我想比较两个十进制值,但我收到错误。我用了

if [ "$(echo $result1 '>' $result2 | bc -l)" -eq 1 ];then

as suggested by the other Stack Overflow thread.

正如其他Stack Overflow线程所建议的那样。

I am getting errors.

我收到了错误。

What is the correct way to go about this?

这是怎么回事?

7 个解决方案

#1


31  

You can do it using Bash's numeric context:

你可以使用Bash的数字上下文来做到这一点:

if (( $(echo "$result1 > $result2" | bc -l) )); then

bc will output 0 or 1 and the (( )) will interpret them as false or true respectively.

bc将输出0或1,(())将分别解释为false或true。

The same thing using AWK:

使用AWK同样的事情:

if (( $(echo "$result1 $result2" | awk '{print ($1 > $2)}') )); then

#2


8  

if awk 'BEGIN{exit ARGV[1]>ARGV[2]}' "$z" "$y"
then
  echo z not greater than y
else
  echo z greater than y
fi

#3


0  

Following up on Dennis's reply:

跟进丹尼斯的回复:

Although his reply is correct for decimal points, bash throws (standard_in) 1: syntax error with floating point arithmetic.

虽然他的回答对于小数点是正确的,但是bash抛出(standard_in)1:浮点运算的语法错误。

result1=12
result2=1.27554e-05


if (( $(echo "$result1 > $result2" | bc -l) )); then
    echo "r1 > r2"
else
    echo "r1 < r2"
fi

This returns incorrect output with a warning although with an exit code of 0.

虽然退出代码为0,但会返回错误输出并显示警告。

(standard_in) 1: syntax error
r1 < r2

(standard_in)1:语法错误r1

While there is no clear solution to this (discussion thread 1 and thread 2), I used following partial fix by rounding off floating point results using awk followed by use of bc command as in Dennis's reply and this thread

虽然没有明确的解决方案(讨论主题1和主题2),但我使用了awk,然后使用bc命令舍入浮点结果,如Dennis的回复和此主题一样,使用了以下部分修复

Round off to a desired decimal place: Following will get recursive directory space in TB with rounding off at the second decimal place.

舍入到所需的小数位:以下将获得TB中的递归目录空间,并在小数点后第二位舍入。

result2=$(du -s "/home/foo/videos" | tail -n1 | awk '{$1=$1/(1024^3); printf "%.2f", $1;}')

You can then use bash arithmetic as above or using [[ ]] enclosure as in following thread.

然后,您可以使用上面的bash算法或使用[[]] enclosure作为后续线程。

if (( $(echo "$result1 > $result2" | bc -l) )); then
    echo "r1 > r2"
else
    echo "r1 < r2"
fi

or using -eq operator where bc output of 1 is true and 0 is false

或者使用-eq运算符,其中bc输出1为真,0为假

if [[ $(bc <<< "$result1 < $result2") -eq 1 ]]; then
    echo "r1 < r2"
else
    echo "r1 > r2"
fi

#4


0  

if [[ `echo "$result1 $result2" | awk '{print ($1 > $2)}'` == 1 ]]; then
  echo "$result1 is greater than $result2"
fi

#5


-1  

You can also echo an if...else statement to bc.

您还可以将一个if ... else语句回显给bc。

- echo $result1 '>' $result2
+ echo "if (${result1} > ${result2}) 1 else 0"

(
#export IFS=2  # example why quoting is important
result1="2.3" 
result2="1.7" 
if [ "$(echo $result1 '>' $result2 | bc -l)" -eq 1 ]; then echo yes; else echo no;fi
if [ "$(echo "if (${result1} > ${result2}) 1 else 0" | bc -l)" -eq 1 ];then echo yes; else echo no; fi
if echo $result1 $result2 | awk '{exit !( $1 > $2)}'; then echo yes; else echo no; fi
)

#6


-2  

Can't bash force type conversion? For example:

不能猛击力型转换?例如:

($result1 + 0) < ($result2 + 0)

#7


-3  

Why use bc ?

为什么要用bc?

for i in $(seq -3 0.5 4) ; do echo $i ; if [[ (( "$i" < 2 )) ]] ; then echo "... is < 2";fi; done

The only problem : the comparison "<" doesn't work with negative numbers : they are taken as their absolute value.

唯一的问题:比较“<”不适用于负数:它们被视为绝对值。

#1


31  

You can do it using Bash's numeric context:

你可以使用Bash的数字上下文来做到这一点:

if (( $(echo "$result1 > $result2" | bc -l) )); then

bc will output 0 or 1 and the (( )) will interpret them as false or true respectively.

bc将输出0或1,(())将分别解释为false或true。

The same thing using AWK:

使用AWK同样的事情:

if (( $(echo "$result1 $result2" | awk '{print ($1 > $2)}') )); then

#2


8  

if awk 'BEGIN{exit ARGV[1]>ARGV[2]}' "$z" "$y"
then
  echo z not greater than y
else
  echo z greater than y
fi

#3


0  

Following up on Dennis's reply:

跟进丹尼斯的回复:

Although his reply is correct for decimal points, bash throws (standard_in) 1: syntax error with floating point arithmetic.

虽然他的回答对于小数点是正确的,但是bash抛出(standard_in)1:浮点运算的语法错误。

result1=12
result2=1.27554e-05


if (( $(echo "$result1 > $result2" | bc -l) )); then
    echo "r1 > r2"
else
    echo "r1 < r2"
fi

This returns incorrect output with a warning although with an exit code of 0.

虽然退出代码为0,但会返回错误输出并显示警告。

(standard_in) 1: syntax error
r1 < r2

(standard_in)1:语法错误r1

While there is no clear solution to this (discussion thread 1 and thread 2), I used following partial fix by rounding off floating point results using awk followed by use of bc command as in Dennis's reply and this thread

虽然没有明确的解决方案(讨论主题1和主题2),但我使用了awk,然后使用bc命令舍入浮点结果,如Dennis的回复和此主题一样,使用了以下部分修复

Round off to a desired decimal place: Following will get recursive directory space in TB with rounding off at the second decimal place.

舍入到所需的小数位:以下将获得TB中的递归目录空间,并在小数点后第二位舍入。

result2=$(du -s "/home/foo/videos" | tail -n1 | awk '{$1=$1/(1024^3); printf "%.2f", $1;}')

You can then use bash arithmetic as above or using [[ ]] enclosure as in following thread.

然后,您可以使用上面的bash算法或使用[[]] enclosure作为后续线程。

if (( $(echo "$result1 > $result2" | bc -l) )); then
    echo "r1 > r2"
else
    echo "r1 < r2"
fi

or using -eq operator where bc output of 1 is true and 0 is false

或者使用-eq运算符,其中bc输出1为真,0为假

if [[ $(bc <<< "$result1 < $result2") -eq 1 ]]; then
    echo "r1 < r2"
else
    echo "r1 > r2"
fi

#4


0  

if [[ `echo "$result1 $result2" | awk '{print ($1 > $2)}'` == 1 ]]; then
  echo "$result1 is greater than $result2"
fi

#5


-1  

You can also echo an if...else statement to bc.

您还可以将一个if ... else语句回显给bc。

- echo $result1 '>' $result2
+ echo "if (${result1} > ${result2}) 1 else 0"

(
#export IFS=2  # example why quoting is important
result1="2.3" 
result2="1.7" 
if [ "$(echo $result1 '>' $result2 | bc -l)" -eq 1 ]; then echo yes; else echo no;fi
if [ "$(echo "if (${result1} > ${result2}) 1 else 0" | bc -l)" -eq 1 ];then echo yes; else echo no; fi
if echo $result1 $result2 | awk '{exit !( $1 > $2)}'; then echo yes; else echo no; fi
)

#6


-2  

Can't bash force type conversion? For example:

不能猛击力型转换?例如:

($result1 + 0) < ($result2 + 0)

#7


-3  

Why use bc ?

为什么要用bc?

for i in $(seq -3 0.5 4) ; do echo $i ; if [[ (( "$i" < 2 )) ]] ; then echo "... is < 2";fi; done

The only problem : the comparison "<" doesn't work with negative numbers : they are taken as their absolute value.

唯一的问题:比较“<”不适用于负数:它们被视为绝对值。