我正在尝试做一些常见的事情:在shell脚本中解析用户输入.如果用户提供了有效的整数,则脚本会执行一项操作,如果无效,则执行其他操作.麻烦的是,我还没有找到一种简单(而且相当优雅)的方式 - 我不想用char来区分char.
我知道这一定很容易,但我不知道如何.我可以用十几种语言来做,但不是BASH!
在我的研究中,我发现了这个:
正则表达式,用于测试字符串是否包含基数为10的有效实数
其中有一个关于正则表达式的答案,但据我所知,这是C(以及其他)中可用的函数.尽管如此,它看起来像是一个很好的答案,所以我用grep尝试了它,但是grep不知道该怎么做.我试过-P在我的盒子上意味着把它当作PERL regexp - nada.Dash E(-E)也没有用.并且-F都没有.
为了清楚起见,我正在尝试这样的东西,寻找任何输出 - 从那里,我将破解脚本以利用我得到的任何东西.(IOW,我期待一个不合格的输入在有效行重复时不返回任何内容.)
snafu=$(echo "$2" | grep -E "/^[-+]?(?:\.[0-9]+|(?:0|[1-9][0-9]*)(?:\.[0-9]*)?)$/") if [ -z "$snafu" ] ; then echo "Not an integer - nothing back from the grep" else echo "Integer." fi
有人请说明这是最容易做到的吗?
坦率地说,在我看来,这是TEST的缩影.它应该有这样的旗帜
if [ -I "string" ] ; then echo "String is a valid integer." else echo "String is not a valid integer." fi
Ignacio Vazq.. 171
[[ $var =~ ^-?[0-9]+$ ]]
的^
表示输入模式的开始
该-
是字符" - "
的?
意思是"0或前述的1(-
)"
的+
意思是"1或多个前述的([0-9]
)"
的$
指示输入图案的端部
因此正则表达式匹配可选-
(对于负数的情况),后跟一个或多个十进制数字.
参考文献:
http://www.tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
"+"表示"前面的1个或多个","$"表示输入模式的结束.所以正则表达式匹配一个可选的`-`后跟一个或多个十进制数字. (10认同)
谢谢伊格纳西奥,我会在一秒钟内尝试一下.你介意解释一下,这样我可以学到一点吗?我收集它读取,"在字符串的开头(^),减号( - )是可选的(?),后跟0到9之间的任意数量的字符,包括"......然后可能+ $是吗?谢谢. (3认同)
小智.. 61
哇......这里有很多好的解决方案!在上述所有解决方案中,我同意@nortally使用-eq
一个班轮是最酷的.
我正在运行GNU bash,版本4.1.5
(Debian).我也在ksh上检查了这个(SunSO 5.10).
这是我的检查版本是否$1
为整数:
if [ "$1" -eq "$1" ] 2>/dev/null then echo "$1 is an integer !!" else echo "ERROR: first parameter must be an integer." echo $USAGE exit 1 fi
这种方法也考虑了负数,其他一些解决方案会产生错误的否定结果,并且它将允许前缀"+"(例如+30),这显然是一个整数.
结果:
$ int_check.sh 123 123 is an integer !! $ int_check.sh 123+ ERROR: first parameter must be an integer. $ int_check.sh -123 -123 is an integer !! $ int_check.sh +30 +30 is an integer !! $ int_check.sh -123c ERROR: first parameter must be an integer. $ int_check.sh 123c ERROR: first parameter must be an integer. $ int_check.sh c123 ERROR: first parameter must be an integer.
解释后,Ignacio Vazquez-Abrams提供的解决方案也很整洁(如果你喜欢正则表达式).但是,它不会处理带+
前缀的正数,但可以很容易地修复如下:
[[ $var =~ ^[-+]?[0-9]+$ ]]
你的解决方案和正则表达式之间有一个显着的区别:整数的大小被检查为bash限制(在我的计算机上它是64位).此限制未达到正则表达式解决方案.因此,对于64位计算机上的数字严格大于9223372036854775807,您的解决方案将失败. (2认同)
正如我最近发现的那样,[有些警告](http://stackoverflow.com/a/808740/1858225). (2认同)
tripleee.. 26
这里的聚会迟到了.我非常惊讶没有一个答案提到最简单,最快速,最便携的解决方案; 该case
声明.
case ${variable#[-+]} in *[!0-9]* | '') echo Not a number ;; * ) echo Valid number ;; esac
在比较之前修剪任何符号感觉有点像黑客,但这使得case语句的表达式变得更加简单.
[[ $var =~ ^-?[0-9]+$ ]]
的^
表示输入模式的开始
该-
是字符" - "
的?
意思是"0或前述的1(-
)"
的+
意思是"1或多个前述的([0-9]
)"
的$
指示输入图案的端部
因此正则表达式匹配可选-
(对于负数的情况),后跟一个或多个十进制数字.
参考文献:
http://www.tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
哇......这里有很多好的解决方案!在上述所有解决方案中,我同意@nortally使用-eq
一个班轮是最酷的.
我正在运行GNU bash,版本4.1.5
(Debian).我也在ksh上检查了这个(SunSO 5.10).
这是我的检查版本是否$1
为整数:
if [ "$1" -eq "$1" ] 2>/dev/null then echo "$1 is an integer !!" else echo "ERROR: first parameter must be an integer." echo $USAGE exit 1 fi
这种方法也考虑了负数,其他一些解决方案会产生错误的否定结果,并且它将允许前缀"+"(例如+30),这显然是一个整数.
结果:
$ int_check.sh 123 123 is an integer !! $ int_check.sh 123+ ERROR: first parameter must be an integer. $ int_check.sh -123 -123 is an integer !! $ int_check.sh +30 +30 is an integer !! $ int_check.sh -123c ERROR: first parameter must be an integer. $ int_check.sh 123c ERROR: first parameter must be an integer. $ int_check.sh c123 ERROR: first parameter must be an integer.
解释后,Ignacio Vazquez-Abrams提供的解决方案也很整洁(如果你喜欢正则表达式).但是,它不会处理带+
前缀的正数,但可以很容易地修复如下:
[[ $var =~ ^[-+]?[0-9]+$ ]]
这里的聚会迟到了.我非常惊讶没有一个答案提到最简单,最快速,最便携的解决方案; 该case
声明.
case ${variable#[-+]} in *[!0-9]* | '') echo Not a number ;; * ) echo Valid number ;; esac
在比较之前修剪任何符号感觉有点像黑客,但这使得case语句的表达式变得更加简单.
为了便于预先Bash 3.1(当=~
引入测试时),使用expr
.
if expr "$string" : '-\?[0-9]\+$' >/dev/null then echo "String is a valid integer." else echo "String is not a valid integer." fi
expr STRING : REGEX
搜索在STRING开始时锚定的REGEX,回显第一组(或匹配的长度,如果没有)并返回成功/失败.这是旧的正则表达式语法,因此是多余的\
. -\?
表示"可能-
",[0-9]\+
表示"一个或多个数字",$
表示"字符串结尾".
Bash也支持扩展的globs,但我不记得从哪个版本开始.
shopt -s extglob case "$string" of @(-|)[0-9]*([0-9])) echo "String is a valid integer." ;; *) echo "String is not a valid integer." ;; esac # equivalently, [[ $string = @(-|)[0-9]*([0-9])) ]]
@(-|)
表示" -
或没有",[0-9]
表示"数字",*([0-9])
表示"零或更多数字".
我喜欢使用-eq
测试的解决方案,因为它基本上是一个单行.
我自己的解决方案是使用参数扩展来丢弃所有数字,看看是否还有什么东西.(我还在使用3.0,没有使用过[[
或expr
之前,但很高兴见到它们.)
if [ "${INPUT_STRING//[0-9]}" = "" ]; then # yes, natural number else # no, has non-numeral chars fi