BASH:测试参数是一个数字列表

时间:2016-12-17 23:33:44

标签: regex linux bash

我试图测试bash脚本的无数个参数("$@")是数字("#""#.#"".#",{{1} })由空格分隔(即"#.")。我试过了:

# # # # ...

类似于我在this answer中找到的内容,但我得到了:

[ "$@" -eq "$@" ]

我也试过正则表达式,但似乎一旦正则表达式满足,之后就会出现任何事情。这是我的代码:

"[: too many arguments"

它还需要不允许if (($# >=1)) && [[ "$@" =~ ^-?[[:digit:]]*\.?[[:digit:]]+ ]]; then "#.."

4 个答案:

答案 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),八进制(\033033),其他基础(32#wer)或算术表达式(2+29/79**3等)。

在这种情况下,该数字应仅使用数字,一个(可选)符号和一个(可选)点。

此正则表达式检查以上大部分内容:

regex='^([+-]?)([0]*)(([1-9][0-9]*([.][0-9]+)?)|([.][0-9]+))$'

用语言说:

  • 可选符号(+-
  • 后跟任意数量的可选零。
  • 其次是(... | ... | ...)

    1. 数字[1-9]后跟零个或多个数字[0-9](可选)后跟一个点和数字。
    2. 没有数字后跟一个点后跟一个或多个数字。

像这样(因为你将问题标记为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