Ric*_*d T 108 string bash integer if-statement
我正在尝试做一些常见的事情:在shell脚本中解析用户输入.如果用户提供了有效的整数,则脚本会执行一项操作,如果无效,则执行其他操作.麻烦的是,我还没有找到一种简单(而且相当优雅)的方式 - 我不想用char来区分char.
我知道这一定很容易,但我不知道如何.我可以用十几种语言来做,但不是BASH!
在我的研究中,我发现了这个:
其中有一个关于正则表达式的答案,但据我所知,这是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
Run Code Online (Sandbox Code Playgroud)
有人请说明这是最容易做到的吗?
坦率地说,在我看来,这是TEST的缩影.它应该有这样的旗帜
if [ -I "string" ] ;
then
echo "String is a valid integer."
else
echo "String is not a valid integer."
fi
Run Code Online (Sandbox Code Playgroud)
Ign*_*ams 171
[[ $var =~ ^-?[0-9]+$ ]]
Run Code Online (Sandbox Code Playgroud)
^表示输入模式的开始-是字符" - "?意思是"0或前述的1(-)"+意思是"1或多个前述的([0-9])"$指示输入图案的端部因此正则表达式匹配可选-(对于负数的情况),后跟一个或多个十进制数字.
参考文献:
小智 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
Run Code Online (Sandbox Code Playgroud)
这种方法也考虑了负数,其他一些解决方案会产生错误的否定结果,并且它将允许前缀"+"(例如+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.
Run Code Online (Sandbox Code Playgroud)
解释后,Ignacio Vazquez-Abrams提供的解决方案也很整洁(如果你喜欢正则表达式).但是,它不会处理带+前缀的正数,但可以很容易地修复如下:
[[ $var =~ ^[-+]?[0-9]+$ ]]
Run Code Online (Sandbox Code Playgroud)
tri*_*eee 26
这里的聚会迟到了.我非常惊讶没有一个答案提到最简单,最快速,最便携的解决方案; 该case声明.
case ${variable#[-+]} in
*[!0-9]* | '') echo Not a number ;;
* ) echo Valid number ;;
esac
Run Code Online (Sandbox Code Playgroud)
在比较之前修剪任何符号感觉有点像黑客,但这使得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
Run Code Online (Sandbox Code Playgroud)
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])) ]]
Run Code Online (Sandbox Code Playgroud)
@(-|)表示" -或没有",[0-9]表示"数字",*([0-9])表示"零或更多数字".
我喜欢使用-eq测试的解决方案,因为它基本上是一个单行.
我自己的解决方案是使用参数扩展来丢弃所有数字,看看是否还有什么东西.(我还在使用3.0,没有使用过[[或expr之前,但很高兴见到它们.)
if [ "${INPUT_STRING//[0-9]}" = "" ]; then
# yes, natural number
else
# no, has non-numeral chars
fi
Run Code Online (Sandbox Code Playgroud)
您可以去掉非数字并进行比较。这是一个演示脚本:
for num in "44" "-44" "44-" "4-4" "a4" "4a" ".4" "4.4" "-4.4" "09"
do
match=${num//[^[:digit:]]} # strip non-digits
match=${match#0*} # strip leading zeros
echo -en "$num\t$match\t"
case $num in
$match|-$match) echo "Integer";;
*) echo "Not integer";;
esac
done
Run Code Online (Sandbox Code Playgroud)
测试输出如下所示:
44 44 整数 -44 44 整数 44- 44 非整数 4-4 44 非整数 a4 4 非整数 4a 4 非整数 .4 4 非整数 4.4 44 非整数 -4.4 44 非整数 09 9 非整数
小智 5
这是另一种看法(仅使用 test 内置命令及其返回码):
function is_int() { test "$@" -eq "$@" 2> /dev/null; }
input="-123"
if is_int "$input"
then
echo "Input: ${input}"
echo "Integer: ${input}"
else
echo "Not an integer: ${input}"
fi
Run Code Online (Sandbox Code Playgroud)