Shell变量值在预定义的范围内

时间:2014-11-05 05:16:02

标签: linux bash shell scripting

我想要一个变量,其值应该在已定义的范围内。

例如。

变量DAY = $ 1

只应获得Mon,Tue,Wed,Then,Fri,Sat,Sun等值。

如果用户输入其他内容,则不会接受。

我知道我可以通过定义数组或通常是存储所有日期的变量,然后检查变量DAY在" for或while"循环。

但我想要没有循环的最简单方法。

提前致谢。

4 个答案:

答案 0 :(得分:2)

使用扩展的glob支持来完全匹配一个选项列表。

range="Mon|Tue|Wed|Thu|Fri"
read day
if [[ $day = @($range) ]]; then
    echo "$day is valid"
else
    echo "$day is not valid"
fi

答案 1 :(得分:1)

如果不使用循环,您可以执行以下操作:

EOL=$'\n'
arr=(Mon Tue Wed Thus Fri Sat Sun)
read -p 'Enter day value: ' day
Tue

[[ $(printf "$EOL%s$EOL" "${arr[@]}") == *"$EOL$day$EOL"* ]] &&
   echo "in range" || echo "not in range"
in range

read -p 'Enter day value: ' day
ue We
[[ $(printf "$EOL%s$EOL" "${arr[@]}") == *"$EOL$day$EOL"* ]] &&
   echo "in range" || echo "not in range"
not in range

答案 2 :(得分:0)

稍微扩大anubhava的答案:

arr=(Mon Tue Wed Thus Fri Sat Sun)
read -p 'Enter day value: ' day
case "${arr[@]}" in *"$day"*) echo "in range";; esac

基本上,这是构建一个数组,将其转换为字符串,并在其上进行模式匹配。

case表达式的上下文中,"${arr[@]}""${arr[*]}"之间没有区别;我个人会坚持使用*,这使您更清楚地构建一个大字符串而不是单独的字符串列表。

使用这组特定的值,您不必担心子字符串重叠,但上述检查仍然过于宽容。例如,如果您输入u,则会在范围"中将其视为"。这可能不是你想要的。

更精确的测试将是这样的:

case "${arr[*]}" in
   "$day "*|*" $day "*|*" $day") echo "in range";;
    *) echo "not in range";;
esac

这仍然允许用户输入多天,因为" Mon Tue"或类似的;在此特定情况下,一种简单的方法是将read行从read day更改为read day _

"$day "*模式将在数组的开头匹配(因此,如果他们在这种情况下输入Mon)。 *" $day"模式将匹配数组末尾(Fri),*" $day "*模式将与其余模式匹配。除了精确的日期字符串之外别无其他。

另外,在这里您可以看到如何处理else案例 - *的模式匹配任何尚未与其他内容匹配的内容,因此它相当于else中的case

答案 3 :(得分:0)

实际上不需要阵列。

read -r day
case ' Mon Tue Wed Thu Fri Sat Sun ' in
  *" $day "*)
    echo "in range";;
  *) echo "not in range";;
esac

注意字符串表达式周围的空格。

如果你需要严格,你应该拒绝“星期三”,这是不行的。它需要第二个case包装,它很笨重但不完全笨重。