在不干扰无效选项的情况下检测负数(以 - 开头)
Detecting negative numbers without interfering with invalid options (starting with -)
我有一个 bash 函数来验证数值(正数和负数,包括整数、浮点数和科学记数法)。
使用参数解析循环,我还想处理无效选项(从 -
开始,但会干扰用户提供的负数)。
while (( $# > 0 )); do
opt=""
case $opt in
("-I") fm="I" ; shift 1 ;; # integers
("-F") fm="F" ; shift 1 ;; # floating point
("-E") fm="E" ; shift 1 ;; # exponential notation
("--") shift 1 ; break ;;
# ----------------------------
("-"*) status=64 ; shift 1 ;;
# ----------------------------
(*) break ;;
# ----------------------------
esac # case ends here
done # while ends here
对于用户调用的情况,我已经将 --
检测为选项结束的指示符。但是当从另一个函数调用函数时,我无法事先知道该值是正数还是负数。
如何检测参数是否包含会使参数无效的字符?然后我可以在"-"*
部分引入检查。
您可以测试模式 ("-"[0-9]*)
,然后假设(此时)甚至 -5X
也是一个数字。好吧,这也不是一个有效的选项,如果您稍后对数字参数进行有效性检查,您无论如何都会发现这种情况。
如果我们只关注整数,另一种方法是显式测试错误情况:模式 -*[!0-9]*
匹配以连字符开头并在后面包含某些内容 non-numeric 的参数,如果此模式匹配,您知道您有一个非法选项而不是数字。
在你的情况下,第一种方法似乎更明智,因为你似乎也允许小数。因此,什么是有效数字取决于之前设置的选项(-I
或 -F
),无论如何您都必须根据您期望的数字类型进行验证。为了验证指数格式,我会进行正则表达式匹配,而不是 glob 模式 - 取决于您允许的指数格式类型:
if [[ $opt =~ ^[-+]?[0-9]+([.][0-9]+)?E[-+]?[0-9]+$ ]]
then
# We have a valid number in exponential notation
...
当然,要使用的确切模式取决于指数表示法中允许的变化。
除此之外,您的程序仍然存在问题,因为您允许将 -I
和 -E
都传递给您的命令。在您当前的实现中,最后一个被使用,而前一个被默默地忽略。相反,我会重新考虑您的程序设计,因为可能只提供一个选项(-I、-E 或 -F)。这必须是第一个选项,第二个参数之后的所有内容都必须是数字。
我有一个 bash 函数来验证数值(正数和负数,包括整数、浮点数和科学记数法)。
使用参数解析循环,我还想处理无效选项(从 -
开始,但会干扰用户提供的负数)。
while (( $# > 0 )); do
opt=""
case $opt in
("-I") fm="I" ; shift 1 ;; # integers
("-F") fm="F" ; shift 1 ;; # floating point
("-E") fm="E" ; shift 1 ;; # exponential notation
("--") shift 1 ; break ;;
# ----------------------------
("-"*) status=64 ; shift 1 ;;
# ----------------------------
(*) break ;;
# ----------------------------
esac # case ends here
done # while ends here
对于用户调用的情况,我已经将 --
检测为选项结束的指示符。但是当从另一个函数调用函数时,我无法事先知道该值是正数还是负数。
如何检测参数是否包含会使参数无效的字符?然后我可以在"-"*
部分引入检查。
您可以测试模式 ("-"[0-9]*)
,然后假设(此时)甚至 -5X
也是一个数字。好吧,这也不是一个有效的选项,如果您稍后对数字参数进行有效性检查,您无论如何都会发现这种情况。
如果我们只关注整数,另一种方法是显式测试错误情况:模式 -*[!0-9]*
匹配以连字符开头并在后面包含某些内容 non-numeric 的参数,如果此模式匹配,您知道您有一个非法选项而不是数字。
在你的情况下,第一种方法似乎更明智,因为你似乎也允许小数。因此,什么是有效数字取决于之前设置的选项(-I
或 -F
),无论如何您都必须根据您期望的数字类型进行验证。为了验证指数格式,我会进行正则表达式匹配,而不是 glob 模式 - 取决于您允许的指数格式类型:
if [[ $opt =~ ^[-+]?[0-9]+([.][0-9]+)?E[-+]?[0-9]+$ ]]
then
# We have a valid number in exponential notation
...
当然,要使用的确切模式取决于指数表示法中允许的变化。
除此之外,您的程序仍然存在问题,因为您允许将 -I
和 -E
都传递给您的命令。在您当前的实现中,最后一个被使用,而前一个被默默地忽略。相反,我会重新考虑您的程序设计,因为可能只提供一个选项(-I、-E 或 -F)。这必须是第一个选项,第二个参数之后的所有内容都必须是数字。