我试图测试bash脚本的无数个参数("$@"
)是数字("#"
,"#.#"
,".#"
,{{1} })由空格分隔(即"#."
)。我试过了:
# # # # ...
类似于我在this answer中找到的内容,但我得到了:
[ "$@" -eq "$@" ]
我也试过正则表达式,但似乎一旦正则表达式满足,之后就会出现任何事情。这是我的代码:
"[: too many arguments"
它还需要不允许if (($# >=1)) && [[ "$@" =~ ^-?[[:digit:]]*\.?[[:digit:]]+ ]]; then
或"#.."
答案 0 :(得分:2)
我不认为[ "$@" -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程序bash程序将数字除以它自己。
如果是有效数字将返回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
答案 1 :(得分:1)
$@
是一个字符串数组。您可能希望一次处理一个字符串,而不是一起处理。
for i; do
if [[ $i =~ ^-?[[:digit:]]+\.?[[:digit:]]*$ ]] || [[ $i =~ ^-?\.?[[:digit:]]+$ ]]; then
echo yes - $i
else
echo no - $i
fi
done
答案 2 :(得分:0)
在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.
答案 3 :(得分:0)
我将假设您的意思是十进制数字,仅限于使用点表示小数点的国家/地区的整数或浮点数。并且此国家/地区不使用分组字符(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