bash-测试MM在01和12之间

bash-测试MM在01和12之间,bash,Bash,我有$MM。它可以是: 01-12 但不是1-12,即每个单个数字前面都有一个0,1=01,2=02等 我需要编写一个测试,确保MM是有效的,如果不是,就失败。我试过: MM=09 if [[ "$MM" -le 0 ]] && [[ "$MM" -ge 13 ]]; then echo "MM is not between 01 and 12" fi 错误: [[: 09: value too great for base (error token is "09") 我

我有$MM。它可以是: 01-12

但不是1-12,即每个单个数字前面都有一个0,1=01,2=02等

我需要编写一个测试,确保MM是有效的,如果不是,就失败。我试过:

MM=09
if [[ "$MM" -le 0 ]] && [[ "$MM" -ge 13 ]]; then
  echo "MM is not between 01 and 12"
fi
错误:

[[: 09: value too great for base (error token is "09")
我还尝试了各种组合:

MM=13
if [ $MM -le 0 ] && [ $MM -ge 13 ]; then
  echo "MM is not between 01 and 12"
fi
当MM为预期值13时,不显示任何内容

MM=13
if [ $MM <= 0 ] && [ $MM => 13 ]; then
  echo "MM is not between 01 and 12"
fi
我知道我在这里做了一些根本错误的事情,我只是不确定这是什么。我还需要此逻辑来应用类似的检查:

DD需要介于01-31之间 hh需要介于00-23之间 mm需要介于00-59之间


谢谢

首先,前导0使shell将其解释为八进制数,而09是无效的八进制数,因此您将得到:09:值对于基本错误来说太大

您可以使用BASH regex进行此验证:

mm='09'

[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
valid

mm='9'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
invalid

mm='13'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
invalid

mm='12'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
valid

首先,前导0使shell将其解释为八进制数,而09是无效的八进制数,因此您将得到:09:值对于基错误来说太大

您可以使用BASH regex进行此验证:

mm='09'

[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
valid

mm='9'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
invalid

mm='13'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
invalid

mm='12'
[[ $mm =~ ^(0[1-9]|1[0-2])$ ]] && echo "valid" || echo "invalid"
valid

只需使用算术比较,指定基数:

if (( 10#$mm < 1 || 10#$mm > 12 )); then
  echo "mm is not between 1 and 12"
fi
或者类似地

if (( 10#$mm >= 1 && 10#$mm <= 12 )); then
  echo "mm is between 1 and 12"
fi
通过在数字/变量展开前使用基数来指定基数。这里我们需要基数10,因此扩展$mm前面的10。请参见本节末尾附近的内容


使用正则表达式的另一个答案是好的,但没有正确的语义,并且在更复杂的范围内可能会非常尴尬。

只需使用算术比较,指定基数:

if (( 10#$mm < 1 || 10#$mm > 12 )); then
  echo "mm is not between 1 and 12"
fi
或者类似地

if (( 10#$mm >= 1 && 10#$mm <= 12 )); then
  echo "mm is between 1 and 12"
fi
通过在数字/变量展开前使用基数来指定基数。这里我们需要基数10,因此扩展$mm前面的10。请参见本节末尾附近的内容

使用正则表达式的另一个答案是好的,但是没有正确的语义,并且在更复杂的范围内可能会非常尴尬。

如果您想要与sh兼容,case语句非常方便

case $MM in ? | ???* | *[!0-9]* | 1[3-9] | [2-9]? | 00) echo Invalid;; esac
这会依次触发太短、太长、非数字、小于20的太大、其他太大的数字和全零。

如果您希望与sh兼容,case语句非常方便

case $MM in ? | ???* | *[!0-9]* | 1[3-9] | [2-9]? | 00) echo Invalid;; esac

这会依次触发太短、太长、非数字、小于20的太大、其他太大的数字和全零。

前缀0表示数字为八进制;八进制系统中不存在数字8和9,前缀0表示数字为八进制;八进制中不存在数字8和9。您能解释一下为什么当MM=11时[$MM=~^0[1-9].[10-12]$]]不起作用吗?MM='11'&[$MM=~^0[1-9].[1[0-2]$]&&echo valid | echo valid prints对我有效这很好。我只是好奇为什么[10-12]不起作用。[10-12]并不意味着匹配10到12之间的所有数字。参考这篇好的教程:你能解释一下为什么当MM=11时[$MM=~^0[1-9]|[10-12]$]]不起作用吗?MM='11'&&[$MM=~^0[1-9]| 1[0-2]$]&&echo-valid | | echo-invalid-prints-valid-for-meyes效果很好。我只是好奇为什么[10-12]不起作用。[10-12]并不意味着匹配10到12之间的所有数字。请参考本教程:但这并不能确保字段始终是两个字符的零填充(如有必要)。可能会添加一个单独的检查。但这并不能确保字段始终是两个字符的零填充,如果必要的话。也许再加一张单独的支票。