Reputation: 405
Below is the file on which I am applying the below unix script.
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 $4}' | awk -F ':' '{print $1}'`
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
I am getting the below result: Please notice that the if condition is being satisfied twice. 05 is not between 5.30 and 6.30 still it returns true. What am I missing here.
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
Upvotes: 0
Views: 39
Reputation: 754280
Various issues are visible:
consolidated.txt
matches, ${Result}
remains False
and the outer loop never terminates.6.30 0.30
is never going to match anything because the end of the range is smaller numerically than the start of the range.time >= start && time <= end
, if the time value is 5.30
then that is going to match both the 4.30 5.30
range (it is equal to the end time) and the 5.30 6.30
range (it is equal to the start time).Unlike Bash, Korn shell does support floating point arithmetic, which is useful.
Instead of the [[ … ]]
and using string comparisons (-ge
, -le
), you should use (( … ))
and (floating point) numeric comparisons (>=
, <
).
Assembling these changes into a single script, and ignoring the Result
variable since it isn't relevant here, you get:
#!/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
Yes, the EOF
at the end of the here document does need to be in the left margin. You could use <<-'EOF'
and indent the end marker EOF
as long as the indentation is tabs, not blanks.
The output from this script is:
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
If you change the <
condition to <=
, which is equivalent to what the question uses, then you get the output:
…
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
…
With the last range left as 6.30 0.30
, the final part of the output would look like:
…
7.00 is between 5.30 and 6.30 False
7.00 is between 6.30 and 0.30 False
Upvotes: 1
Reputation: 1303
The problem you are having is due to the line Time=05;
ksh is not interpreting this as a floating point value. let
will force it to do so.
$ Time=05;echo $Time
05
$ let Time=05;echo $Time
5
Another common idiom is Time=$(echo $Time |bc)
Here is an alternative phrasing for your logic:
$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
The (( ... ))
is a numeric conditional similar to [[ ... ]]
It is designed for use in if
and while
constructs.
You can find more details here in section 6.2.2 of Learning the Korn Shell.
Upvotes: 1