我试图testing一个bash脚本的无限数量的参数( "$@"
)是由空格(即# # # # ...
)。 我努力了:
[ "$@" -eq "$@" ]
类似于我在这个答案中发现,但我得到:
"[: too many arguments"
我也尝试过正则expression式,但似乎一旦正则expression式满足,任何事情都可以在之后发生。 这里是我的代码:
if (($# >=1)) && [[ "$@" =~ ^-?[[:digit:]]*\.?[[:digit:]]+ ]]; then
它也需要不允许"#.."
或"..#"
$@
是一个字符串数组。 你可能想一次处理一个字符串,而不是全部。
for i; do if [[ $i =~ ^-?[[:digit:]]+\.?[[:digit:]]*$ ]] || [[ $i =~ ^-?\.?[[:digit:]]+$ ]]; then echo yes - $i else echo no - $i fi done
我不认为[ "$@" -eq "$@"]
会以某种方式工作。
像这样的循环可以帮助读取每个参数,并检测它是否是一个整数(bash不处理小数):
for i in $@;do if [ "$i" -eq "$i" ] 2>/dev/null then echo "$i is an integer !!" else echo "ERROR: not an integer." fi done
在你的情况下,要确定参数是一个有效的整数/十进制数,而不是所有这些正则表达式ifs,我们可以简单地使用bash的bc程序自己分割数字。
如果是有效的号码将返回1.00
所以在你的情况下,这应该工作:
for i in $@;do if [[ "$(bc <<< "scale=2; $i/$i")" == "1.00" ]] 2>/dev/null;then echo "$i is a number and thus is accepted" else echo "Argument $i not accepted" fi done
输出:
root@debian:# ./bashtest.sh 1 3 5.3 0.31 23. .3 ..2 8.. 1 is a number and thus is accepted 3 is a number and thus is accepted 5.3 is a number and thus is accepted 0.31 is a number and thus is accepted 23. is a number and thus is accepted .3 is a number and thus is accepted Argument ..2 not accepted Argument 8.. not accepted
在bash中有与乘法器语法模式匹配,可以帮助你的问题。 这是一个验证所有参数的脚本:
for ARG ; do [[ "$ARG" = +([0-9]) ]] && echo "$ARG is integer number" && continue [[ "$ARG" = +([0-9]).*([0-9]) ]] && echo "$ARG is float number" && continue [[ "$ARG" = *([0-9]).+([0-9]) ]] && echo "$ARG is float number" && continue [[ "$ARG" = -+([0-9]) ]] && echo "$ARG is negative integer number" && continue [[ "$ARG" = -+([0-9]).*([0-9]) ]] && echo "$ARG is negative float number" && continue [[ "$ARG" = -*([0-9]).+([0-9]) ]] && echo "$ARG is negative float number" && continue echo "$ARG is not a number." done
for循环自动使用脚本接收的参数来加载变量ARG。 循环中的每个测试都将变量的值与模式[0-9]乘以+或*(+为1或更大,*为零或更多)相比较,有时候有多个模式相邻。 以下是输出示例:
$ ./script.sh 123 -123 1.23 -12.3 1. -12. .12 -.12 . -. 1a a1 a 12345.6789 11..11 11.11.11 123 is integer number -123 is negative integer number 1.23 is float number -12.3 is negative float number 1. is float number -12. is negative float number .12 is float number -.12 is negative float number . is not a number. -. is not a number. 1a is not a number. a1 is not a number. a is not a number. 12345.6789 is float number 11..11 is not a number. 11.11.11 is not a number.
我假定你的意思是一个十进制数,限于来自国家使用点表示小数点的整数或浮点数。 而这样的国家不使用分组字符( 1,123,456.00125
)。
不包括:科学( 3e+4
),十六进制( 0x22
),八进制( \033
或033
),其他基数( 32#wer
)或算术表达式( 2+2
9/7
9**3
等)。
在这种情况下,数字只能使用数字,一个(可选)符号和一个(可选)点。
这个正则表达式检查以上大部分内容:
regex='^([+-]?)([0]*)(([1-9][0-9]*([.][0-9]+)?)|([.][0-9]+))$'
用话说:
+
或-
) 接着是(… | … | …)
[1-9]
后跟零个或多个数字[0-9]
(可选),后跟一个点和数字。 像这样(因为你把问题标记为bash):
regex='^([+-]?)([0]*)(([1-9][0-9]*([.][0-9]+)?)|([.][0-9]+))$' [[ $n =~ $regex ]] || { echo "A $n is invalid" >&2; }
这将接受0.0
和.0
有效,但不是0.
也不是0
。
当然,这应该像循环一样完成:
regex='^([+-]?)([0]*)(([1-9][0-9]*([.][0-9]+)?)|([.][0-9]+))$' for n do m=${n//[^0-9.+-]} # Only keep digits, dots and sign. [[ $n != "$m" ]] && { echo "Incorrect characters in $n." >&2; continue; } [[ $m =~ $regex ]] || { echo "A $n is invalid" >&2; continue; } printf '%s\n' "${BASH_REMATCH[1]}${BASH_REMATCH[3]}" done