如果条件不理想的结果

Undesired result if condition

下面是我正在应用以下 unix 脚本的文件。

    0.30 2.30 - - - - - - -
    2.30 3.30 - - NA NA - - -
    3.30 4.30 - - NA NA - - -
    4.30 5.30 - - - - - - -
    5.30 6.30 - - NA NA - - -
    6.30 0.30 - - - - - - -

##Time=`echo $(date) | awk -F ' ' '{print }' | awk -F ':' '{print }'` 
Time=05;
Result="False";
while [[ "${Result}" != "True" ]]
do
    while read -r f1 f2 f3 f4 f5 f6 f7 f8 f9
    do
        if [[ "${Time}" -ge "${f1}" && "${Time}" -le "${f2}" ]]
        then 
                echo $Time is between $f1 $f2 True
                Result="True";
        else
                echo $Time is between $f1 $f2 False
        fi
    done < consolidated.txt
done

我得到以下结果:请注意 if 条件被满足两次。 05 不在 5.30 和 6.30 之间仍然 returns 正确。 我在这里错过了什么。

05 is between 0.30 2.30 False
05 is between 2.30 3.30 False
05 is between 3.30 4.30 False
05 is between 4.30 5.30 True
05 is between 5.30 6.30 True
05 is between 6.30 0.30 False

您遇到的问题是由于行 Time=05; ksh 没有将其解释为浮点值。 let 将强制它这样做。

$ Time=05;echo $Time
05
$ let Time=05;echo $Time
5

另一个常见的成语是Time=$(echo $Time |bc)

这是您的逻辑的替代措辞:

$echo $Time $f1 $f2
05 5.30 6.30
$
$let Time=05     
$ if [[ (( $Time > $f1 )) && (( $Time < $f2 )) ]]
> then 
>        echo $Time is between $f1 $f2 True
> else
>        echo $Time is between $f1 $f2 False
>fi    
5 is between 5.30 6.30 False

(( ... )) 是类似于 [[ ... ]]
的数字条件 它设计用于 ifwhile 结构。

您可以在 Learning the Korn Shell 的第 6.2.2 节中找到更多详细信息 here

可见各种问题:

  • 您代码中的外循环有问题。如果 consolidated.txt 中的 none 个时间范围匹配,${Result} 仍然是 False 并且外循环永远不会终止。
  • 数据中的最后一个时间范围 6.30 0.30 永远不会匹配任何内容,因为范围的末尾在数值上小于范围的开始。
  • 在您使用 time >= start && time <= end 的条件下,如果时间值为 5.30 那么它将匹配 4.30 5.30 范围(等于结束时间)和5.30 6.30范围(等于开始时间)。

与 Bash 不同,Korn shell 支持浮点运算,这很有用。

而不是 [[ … ]] 和使用字符串比较(-ge-le),您应该使用 (( … )) 和(浮点数)数字比较(>=, <).

将这些更改组合到一个脚本中,并忽略 Result 变量,因为它与此处无关,您将得到:

#!/bin/ksh

for Time in 0 3 05 5.30 7.00
do
    while read -r f1 f2 f3 f4 f5 f6 f7 f8 f9
    do
        if (( "${Time}" >= "${f1}" && "${Time}" < "${f2}" ))
        then echo "${Time} is between ${f1} and ${f2} True"
        else echo "${Time} is between ${f1} and ${f2} False"
        fi
    done << EOF
    0.30 2.30 - - - - - - -
    2.30 3.30 - - NA NA - - -
    3.30 4.30 - - NA NA - - -
    4.30 5.30 - - - - - - -
    5.30 6.30 - - NA NA - - -
    6.30 24.00 - - - - - - -
EOF
done

是的,此处文档末尾的 EOF 确实需要在左边距中。您可以使用 <<-'EOF' 并缩进结束标记 EOF,只要缩进是制表符,而不是空格即可。

此脚本的输出是:

0 is between 0.30 and 2.30 False
0 is between 2.30 and 3.30 False
0 is between 3.30 and 4.30 False
0 is between 4.30 and 5.30 False
0 is between 5.30 and 6.30 False
0 is between 6.30 and 24.00 False
3 is between 0.30 and 2.30 False
3 is between 2.30 and 3.30 True
3 is between 3.30 and 4.30 False
3 is between 4.30 and 5.30 False
3 is between 5.30 and 6.30 False
3 is between 6.30 and 24.00 False
05 is between 0.30 and 2.30 False
05 is between 2.30 and 3.30 False
05 is between 3.30 and 4.30 False
05 is between 4.30 and 5.30 True
05 is between 5.30 and 6.30 False
05 is between 6.30 and 24.00 False
5.30 is between 0.30 and 2.30 False
5.30 is between 2.30 and 3.30 False
5.30 is between 3.30 and 4.30 False
5.30 is between 4.30 and 5.30 False
5.30 is between 5.30 and 6.30 True
5.30 is between 6.30 and 24.00 False
7.00 is between 0.30 and 2.30 False
7.00 is between 2.30 and 3.30 False
7.00 is between 3.30 and 4.30 False
7.00 is between 4.30 and 5.30 False
7.00 is between 5.30 and 6.30 False
7.00 is between 6.30 and 24.00 True

如果将<条件更改为<=,这相当于问题使用的内容,那么您将得到输出:

…
5.30 is between 3.30 and 4.30 False
5.30 is between 4.30 and 5.30 True
5.30 is between 5.30 and 6.30 True
5.30 is between 6.30 and 24.00 False
…

将最后一个范围保留为 6.30 0.30,输出的最后部分将如下所示:

…
7.00 is between 5.30 and 6.30 False
7.00 is between 6.30 and 0.30 False