Reputation: 9406
I am trying to do the following using case
in Bash (in Linux).
If X is between 460 and 660, output X information.
If X is between 661 and 800, do something else.
Etc.
Right now this is what I have:
case $MovieRes in
[461-660]*) echo "$MovieName,480p" >> moviefinal ;;
[661-890]*) echo "$MovieName,720p" >> moviefinal ;;
[891-1200]*) echo "$MovieName,1080p" >> moviefinal ;;
*) echo "$MovieName,DVD" >> moviefinal ;;
esac
But somehow many of the ones that are 480p, 720p or 1080p are ending with DVD instead. The variable $MovieRes
is a simple list that shows, for each line, a number between 1 and 1200. Depending on the value, case
decides which "case" to apply.
I would like to know how to actually use case
to accomplish this since it is a bit confusing when dealing with ranges like this.
Upvotes: 38
Views: 79799
Reputation: 41
This is another solution (may be useful for anybody else):
function caseInRange {
if [ $1 -ge $2 ]; then
if [ $1 -lt $3 ]; then echo "$1"; else echo "too high"; fi
else
echo "to low"
fi
}
case $MovieRes in
1) echo "$MovieName" >> moviefinal ;;
"$(caseInRange $MovieRes 460 660)") echo "$MovieName,480p" >> moviefinal ;;
"$(caseInRange $MovieRes 660 890)") echo "$MovieName,720p" >> moviefinal ;;
"$(caseInRange $MovieRes 890 1200)") echo "$MovieName,1080p" >> moviefinal ;;
*) echo "$MovieName,DVD" >> moviefinal ;;
esac
This way you can mix ranges and fixed values.
Upvotes: 1
Reputation: 59
I was looking for the simplest solution and found it difficult to use a case statement with a number range .
Finally i found a really simple solution for zsh :
#!/usr/bin/zsh
case "${var}" in
<0-5461>)
printf "${var} is between 0 and 5461"
;;
<5462-10922>)
printf "${var} is between 5462-10922"
;;
esac
and for Bash :
#!/bin/bash
case $((
(var >= 0 && var <= 5461) * 1 +
(var > 5462 && var <= 10922) * 2)) in
(1) printf "${var} is between 0 and 5461";;
(2) printf "${var} is between 5461 and 10922";;
esac
Hope it helps someone .
Upvotes: 4
Reputation: 7327
Similar issue which might be useful to someone ... Random additional thing I just tried out where it checks also that it is an integer, for me I wanted it to have a preset value, let the user change it, if they input the wrong data it sets to default.
func_set_num_files(){
echo "How many files do you want to create? (input a number 1-10000)"
read X
# 1, is it a number, #2 is it within max range?
if [[ $X != *[!0-9]* ]]; then
if ((1<=X && X<=10000)) ;then
echo "NUM_FILES=$X"
NUM_FILES=$X
else
echo "Invalid input, setting to default value [ $NUM_FILES ].";sleep 3
fi
else
echo "Invalid input, non-numeric values entered, setting to default value [ $NUM_FILES ].";sleep 3
fi
}
Another example using 'case' to check that a variable is in a range of integers :
check that $MAX is a number and that it's between 50-100 :
case $MAX in
''|*[!0-9]*)
echo "The value $MAX is not a number !"
exit 1
;;
*)
if [ $MAX -lt 50 ] || [ $MAX -gt 100 ] ;then
echo "The value $MAX is not between 50-100"
exit 1
fi
echo "Looks like we are good !"
;;
esac
Upvotes: 3
Reputation: 661
Just for the pleasure of subverting case to do as you want,
you can use $((...))
case 1 in
$(($MovieRes<= 460)))echo "$MovieName,???";;
$(($MovieRes<= 660)))echo "$MovieName,480p";;
$(($MovieRes<= 890)))echo "$MovieName,720p";;
$(($MovieRes<=1200)))echo "$MovieName,1080p";;
*)echo "$MovieName,DVD";;
esac >> moviefinal
Upvotes: 36
Reputation: 274720
The bash case
statement doesn't understand number ranges. It understands shell patterns.
The following should work:
case $MovieRes in
46[1-9]|4[7-9][0-9]|5[0-9][0-9]|6[0-5][0-9]|660) echo "$MovieName,480p" >> moviefinal ;;
66[1-9]|6[7-9][0-9]|7[0-9][0-9]|8[0-8][0-9]|890) echo "$MovieName,720p" >> moviefinal ;;
89[1-9]|9[0-9][0-9]|1[0-1][0-9][0-9]|1200) echo "$MovieName,1080p" >> moviefinal ;;
*) echo "$MovieName,DVD" >> moviefinal ;;
esac
However, I'd recommend you use an if-else statement and compare number ranges as in the other answer. A case
is not the right tool to solve this problem. This answer is for explanatory purposes only.
Upvotes: 38
Reputation: 161834
In bash, you can use the arithmetic expression
: ((...))
if ((461<=X && X<=660))
then
echo "480p"
elif ((661<=X && X<=890))
then
echo "720p"
elif ((891<=X && X<=1200))
then
echo "1080p"
else
echo "DVD"
fi >> moviefinal
Upvotes: 46