在shell脚本中合法化浮点数输入


在shell脚本中合法化浮点数输入
 
  咋一看,在一个shell脚本中合法化一个浮点值的过程看起来有些挫,但想想看浮点数也不过就是一个用小数点分割开来的2个整数。联系第5个脚本validint.sh,你会发现浮点数合法化的测试短的让人惊讶。
 
代码:
 
01
#!/bin/sh
02
  
03
 # validfloat.sh -- 测试一个值是否是合法的浮点数
04
 # 注意,这个脚本并不能接受科学记数法形式的数字
05
  
06
 # 为了测试是否合法,我们需要在小数点位置分割数字。
07
 # 然后测试第一个部分,看看是不是一个合法的整数
08
 # 然后测试第二个,看看是不是>=0的整数。
09
 # 所以-30.5合法,-30.-8非法。
10
  
11
 source validint.sh
12
  
13
 validfloat()
14
 {
15
     fvalue="$1"
16
  
17
     if [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
18
          
19
         decimalPart="$(echo $fvalue | cut -d. -f1)"
20
         fractionalPart="$(echo $fvalue | cut -d. -f2)"
21
  
22
         if [ ! -z $decimalPart ]; then
23
             if ! validint "$decimalPart" "" ""; then
24
                 return 1
25
             fi
26
         fi
27
  
28
         if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
29
             echo "Invalid floating-point number: '-' not allowed \
30
 after decimal point" >&2
31
             return 1
32
         fi
33
  
34
         if [ "$fractionalPart" != "" ]; then
35
             if ! validint "$fractionalPart" "0" ""; then
36
                 return 1
37
             fi
38
         fi
39
  
40
         if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then
41
             if [ -z $fractionalPart ]; then
42
                 echo "Invalid floating-point format." >&2
43
             fi
44
         fi
45
  
46
     else
47
         if [ "$fvalue" = "-" ]; then
48
             echo "Invalid floating-point format." >&2
49
             return 1
50
         fi
51
  
52
         if ! validint "$fvalue" "" ""; then
53
             return 1
54
         fi
55
  
56
     fi
57
  
58
     return 0
59
 }
60
  
61
 if validfloat $1; then
62
     echo "$1 is a valid floating-point value"
63
 fi
运行脚本: 
调用函数的时候,如果没有报错信息,返回码是0,给定的数字就是一个合法的浮点数。通过增加下面几行到脚本中来测试下:
1
if validfloat $1; then
2
    echo "$1 is a valid floating-point value"
3
fi
运行结果:
01
./validfloat.sh 1234.56
02
 1234.56 is a valid floating-point value
03
 ./validfloat.sh -1234.56
04
 -1234.56 is a valid floating-point value
05
 ./validfloat.sh -.75
06
 -.75 is a valid floating-point value
07
 ./validfloat.sh -11.-12
08
 Invalid floating-point number: '-' not allowed after decimal point
09
 ./validfloat.sh 1.0344e22
10
 错误的数字格式!只有数字,不能有逗号、空格等
在此提示下,在上面的脚本中用source引入validint.sh的时候,记得把validint中的最后几行测试脚本注释掉,否则会报错的。source的用法可具体参考手册页。
 
分析脚本:
   对上面的脚本的最好的扩展就是让它支持科学记数法。就是最后一个测试的内容。这个并不是
太难。你要测试下有没有'e'或'E',然后将结果分割为3个部分:
  小数点前的部分,只有一个数字;
  小数部分;
  指数部分。
   最后确保每个部分都是整数。
   老七我自己想了一会,写了一个,欢迎大家指正:
 
01
#测试科学记数法
02
 validfloat()
03
 {
04
     fvalue="$1"
05
     delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')"
06
  
07
     if [ ! -z $delimiter ]; then    #测试下是否有e或E
08
  
09
         if [ ${#delimiter} -ne 1 ]; then    #e或E不能有多个
10
             echo "only one e or E."
11
             return 1
12
         fi
13
          
14
         decimalPart="$(echo $fvalue | cut -d. -f1)"                #小数点前部分
15
         part="$(echo $fvalue | cut -d. -f2-)"                    #小数点后部分,注意f2后有一小横,目的是输出剩下的所有域
16
         fractionalPart="$(echo $part | cut "-d$delimiter" -f1)"    #小数点后,e前部分
17
         exponent="$(echo $part | cut "-d$delimiter" -f2)"        #e后部分
18
  
19
         if ! validint "$decimalPart" "-9" "9"; then                #测试小数点前的部分是不是一个数字,即0-9范围内
20
             echo "scientific notation's decimal part abs must in [0-9]."
21
             return 1
22
         fi
23
  
24
         if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then    #测试小数部分第一个符号是不是负号
25
             echo "scientific notation's fractional portion cannot be negative."
26
             return 1
27
         fi
28
  
29
         if [ "$fractionalPart" = "" ]; then    #测试小数部分是不是为空
30
             echo "scientific notation's fractional portion is empty."
31
             return 1
32
         else
33
             if ! validint "$fractionalPart" "" ""; then        #测试小数部分是不是整数
34
                 echo "scientific notation's fractional portion is not integer."
35
                 return 1
36
             fi
37
         fi
38
  
39
         if ! validint "$exponent" "" ""; then
40
             echo "scientific notation's exponent not integer."
41
             return 1
42
         fi
43
      
44
     elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
下面的代码和上面的都一样了。然后测试下:
1
./validfloat2.sh 1.0EEe22   
2
 only one e or E.
3
 ./validfloat2.sh 1.-3E22
4
 scientific notation's fractional portion cannot be negative.
5
 /validfloat2.sh 1.34E-22.35
6
 错误的数字格式!只有数字,不能有逗号、空格等
7
 scientific notation's exponent not integer.
8
 ./validfloat2.sh 1.013E22
9
 1.013E22 is a valid floating-point value
最后,整理下书上的,和自己写的:
 
01
#!/bin/sh
02
 
03
 source validint.sh
04
  
05
 validfloat()
06
 {
07
     fvalue="$1"
08
     delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')"
09
  
10
     if [ ! -z $delimiter ]; then    #测试下是否有e或E
11
  
12
         if [ ${#delimiter} -ne 1 ]; then    #e或E不能有多个
13
             echo "only one e or E."
14
             return 1
15
         fi
16
          
17
         decimalPart="$(echo $fvalue | cut -d. -f1)"                #小数点前部分
18
         part="$(echo $fvalue | cut -d. -f2-)"                    #小数点后部分,注意f2后有一小横,目的是输出剩下的所有域
19
         fractionalPart="$(echo $part | cut "-d$delimiter" -f1)"    #小数点后,e前部分
20
         exponent="$(echo $part | cut "-d$delimiter" -f2)"        #e后部分
21
  
22
         if ! validint "$decimalPart" "-9" "9"; then                #测试小数点前的部分是不是一个数字,即0-9范围内
23
             echo "scientific notation's decimal part abs must in [0-9]."
24
             return 1
25
         fi
26
  
27
         if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then    #测试小数部分第一个符号是不是负号
28
             echo "scientific notation's fractional portion cannot be negative."
29
             return 1
30
         fi
31
  
32
         if [ "$fractionalPart" = "" ]; then    #测试小数部分是不是为空
33
             echo "scientific notation's fractional portion is empty."
34
             return 1
35
         else
36
             if ! validint "$fractionalPart" "" ""; then        #测试小数部分是不是整数
37
                 echo "scientific notation's fractional portion is not integer."
38
                 return 1
39
             fi
40
         fi
41
  
42
         if ! validint "$exponent" "" ""; then
43
             echo "scientific notation's exponent not integer."
44
             return 1
45
         fi
46
      
47
     elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then
48
          
49
         decimalPart="$(echo $fvalue | cut -d. -f1)"
50
         fractionalPart="$(echo $fvalue | cut -d. -f2)"
51
  
52
         if [ ! -z $decimalPart ]; then
53
             if ! validint "$decimalPart" "" ""; then
54
                 return 1
55
             fi
56
         fi
57
  
58
         if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then
59
             echo "Invalid floating-point number: '-' not allowed \
60
 after decimal point" >&2
61
             return 1
62
         fi
63
  
64
         if [ "$fractionalPart" != "" ]; then
65
             if ! validint "$fractionalPart" "0" ""; then
66
                 return 1
67
             fi
68
         fi
69
  
70
         if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then
71
             if [ -z $fractionalPart ]; then
72
                 echo "Invalid floating-point format." >&2
73
             fi
74
         fi
75
  
76
     else
77
         if [ "$fvalue" = "-" ]; then
78
             echo "Invalid floating-point format." >&2
79
             return 1
80
         fi
81
  
82
         if ! validint "$fvalue" "" ""; then
83
             return 1
84
         fi
85
  
86
     fi
87
  
88
     return 0
89
 }
90
  
91
 if validfloat $1; then
92
     echo "$1 is a valid floating-point value"
93
 fi

相关内容

    暂无相关文章