比较 bash 中的浮点值

比较 bash 中的浮点值

我的 if 表达式总是以某种方式计算为 TRUE。 ROTATION 变量是 0.000 或 90.000,一个浮点值或看起来如此

ROTATION="$(mediainfo --Inform="Video;%Rotation%" $VIDEO$ORIGINALEXTENTION)"
echo $ROTATION

ROTATION_PARAMETER=""

if [ $ROTATION -eq 90 ]
then
    ROTATION_PARAMETER=" --rotate=4"
fi

echo $ROTATION_PARAMETER

如何将变量与值进行比较?

答案1

您可以使用 bc 命令来实现此目的:

echo "$ROTATION == 90"|bc

如果为 false,您将得到 0;如果为 true,您将得到 1

PS 请注意,比较等效浮点数并不是编程中最明智的事情:)

答案2

因为它们是字符串,所以您可以将多个串联字符串相互比较。平衡值提供了同时处理多个 shell 测试的简单方法。

[ "${num#90.}${num%[!0]*}" = "90${num%[!0]*}" ] && do_it

但这仅在$num绝对是数字时才有效。您可以验证整数值,例如$num

[ "$num" -eq "$num" ]

或者像这样的浮动:

[ "${#num}${num#*.}" -ne "${num%.*}${#num}" ]

case通常最好...

case ".${num##*[!-.0-9]*}" in
(.|.[!9]*|.9[!0]*|.90.*[!0]*) 
! :;;esac 

就外部实用程序而言,我通常更喜欢dc它,bc因为它可用于执行任意系统命令:

dc -e '[!echo execute arbitrary system command]s=' \
   -e '90 90.0 =='

括号内的所有内容[]都是一个字符串,s保存到名为的数组中,如果主堆栈上的前两个值,=则将其作为命令执行dc(此处为 90 和 90.0) =另一个。!字符串中的第一个运算符是!作为系统命令执行其后面的所有运算符的运算符。您还可以从输入中读取更多dc脚本,以便使用?运算符有条件地执行。

不过,表达式-e语法是 GNUism。您可以使用 Heredoc 获得相同的效果,或者通过管道将命令回显到其标准输入。

例如:

! dc -e '[!kill -PIPE "$PPID"]s= 90 90.0 ==' && do_it

答案3

您可以像比较字符串一样比较值:

{ printf "[ %.3f == %.3f ]\n" $ROTATION 90 | bash ; } && ROTATION_PARAMETER=" --rotate=4"

甚至

[ $(printf "%.3f == %.3f" $ROTATION 90) ] && ROTATION_PARAMETER=" --rotate=4"

请注意,某些语言环境需要使用小数点分隔符,因此,应采用格式。.$ROTATION90,000

答案4

考虑调用一种更适合处理浮点值的脚本语言,类似于:

ROTATION=...
if $( perl -e 'use POSIX "fmod";if(fmod($ENV{ROTATION}, 90.0)<0.001) {exit(0)} else{exit(1)}' )
then...

(可能有向后的退出返回代码)

相关内容