咋一看,在一个shell脚本中合法化一个浮点值的过程看起来有些挫,但想一想看浮点数也不过就是一个用小数点分割开来的2个整数。联系第5个脚本validint.sh,你会发现浮点数合法化的测试短的让人惊讶。 shell
代码: 函数
#!/bin/sh # validfloat.sh -- 测试一个值是不是合法的浮点数 # 注意,这个脚本并不能接受科学记数法形式的数字 # 为了测试是否合法,咱们须要在小数点位置分割数字。 # 而后测试第一个部分,看看是否是一个合法的整数 # 而后测试第二个,看看是否是>=0的整数。 # 因此-30.5合法,-30.-8非法。 source validint.sh validfloat() { fvalue="$1" if [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then decimalPart="$(echo $fvalue | cut -d. -f1)" fractionalPart="$(echo $fvalue | cut -d. -f2)" if [ ! -z $decimalPart ]; then if ! validint "$decimalPart" "" ""; then return 1 fi fi if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then echo "Invalid floating-point number: '-' not allowed \ after decimal point" >&2 return 1 fi if [ "$fractionalPart" != "" ]; then if ! validint "$fractionalPart" "0" ""; then return 1 fi fi if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then if [ -z $fractionalPart ]; then echo "Invalid floating-point format." >&2 fi fi else if [ "$fvalue" = "-" ]; then echo "Invalid floating-point format." >&2 return 1 fi if ! validint "$fvalue" "" ""; then return 1 fi fi return 0 } if validfloat $1; then echo "$1 is a valid floating-point value" fi运行脚本:
if validfloat $1; then echo "$1 is a valid floating-point value" fi运行结果:
./validfloat.sh 1234.56 1234.56 is a valid floating-point value ./validfloat.sh -1234.56 -1234.56 is a valid floating-point value ./validfloat.sh -.75 -.75 is a valid floating-point value ./validfloat.sh -11.-12 Invalid floating-point number: '-' not allowed after decimal point ./validfloat.sh 1.0344e22 错误的数字格式!只有数字,不能有逗号、空格等
在此提示下,在上面的脚本中用source引入validint.sh的时候,记得把validint中的最后几行测试脚本注释掉,不然会报错的。source的用法可具体参考手册页。 测试
分析脚本:
对上面的脚本的最好的扩展就是让它支持科学记数法。就是最后一个测试的内容。这个并非
太难。你要测试下有没有'e'或'E',而后将结果分割为3个部分:
小数点前的部分,只有一个数字;
小数部分;
指数部分。
最后确保每一个部分都是整数。
老七我本身想了一会,写了一个,欢迎你们指正: spa
#测试科学记数法 validfloat() { fvalue="$1" delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')" if [ ! -z $delimiter ]; then #测试下是否有e或E if [ ${#delimiter} -ne 1 ]; then #e或E不能有多个 echo "only one e or E." return 1 fi decimalPart="$(echo $fvalue | cut -d. -f1)" #小数点前部分 part="$(echo $fvalue | cut -d. -f2-)" #小数点后部分,注意f2后有一小横,目的是输出剩下的全部域 fractionalPart="$(echo $part | cut "-d$delimiter" -f1)" #小数点后,e前部分 exponent="$(echo $part | cut "-d$delimiter" -f2)" #e后部分 if ! validint "$decimalPart" "-9" "9"; then #测试小数点前的部分是否是一个数字,即0-9范围内 echo "scientific notation's decimal part abs must in [0-9]." return 1 fi if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then #测试小数部分第一个符号是否是负号 echo "scientific notation's fractional portion cannot be negative." return 1 fi if [ "$fractionalPart" = "" ]; then #测试小数部分是否是为空 echo "scientific notation's fractional portion is empty." return 1 else if ! validint "$fractionalPart" "" ""; then #测试小数部分是否是整数 echo "scientific notation's fractional portion is not integer." return 1 fi fi if ! validint "$exponent" "" ""; then echo "scientific notation's exponent not integer." return 1 fi elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then下面的代码和上面的都同样了。而后测试下:
./validfloat2.sh 1.0EEe22 only one e or E. ./validfloat2.sh 1.-3E22 scientific notation's fractional portion cannot be negative. /validfloat2.sh 1.34E-22.35 错误的数字格式!只有数字,不能有逗号、空格等 scientific notation's exponent not integer. ./validfloat2.sh 1.013E22 1.013E22 is a valid floating-point value最后,整理下书上的,和本身写的:
#!/bin/sh source validint.sh validfloat() { fvalue="$1" delimiter="$(echo $fvalue | sed 's/[^e|^E]//g')" if [ ! -z $delimiter ]; then #测试下是否有e或E if [ ${#delimiter} -ne 1 ]; then #e或E不能有多个 echo "only one e or E." return 1 fi decimalPart="$(echo $fvalue | cut -d. -f1)" #小数点前部分 part="$(echo $fvalue | cut -d. -f2-)" #小数点后部分,注意f2后有一小横,目的是输出剩下的全部域 fractionalPart="$(echo $part | cut "-d$delimiter" -f1)" #小数点后,e前部分 exponent="$(echo $part | cut "-d$delimiter" -f2)" #e后部分 if ! validint "$decimalPart" "-9" "9"; then #测试小数点前的部分是否是一个数字,即0-9范围内 echo "scientific notation's decimal part abs must in [0-9]." return 1 fi if [ "${fractionalPart%${fractionalPart#?}}" = '-' ]; then #测试小数部分第一个符号是否是负号 echo "scientific notation's fractional portion cannot be negative." return 1 fi if [ "$fractionalPart" = "" ]; then #测试小数部分是否是为空 echo "scientific notation's fractional portion is empty." return 1 else if ! validint "$fractionalPart" "" ""; then #测试小数部分是否是整数 echo "scientific notation's fractional portion is not integer." return 1 fi fi if ! validint "$exponent" "" ""; then echo "scientific notation's exponent not integer." return 1 fi elif [ ! -z $(echo $fvalue | sed 's/[^.]//g') ]; then decimalPart="$(echo $fvalue | cut -d. -f1)" fractionalPart="$(echo $fvalue | cut -d. -f2)" if [ ! -z $decimalPart ]; then if ! validint "$decimalPart" "" ""; then return 1 fi fi if [ "${fractionalPart%${fractionalPart#?}}" = "-" ]; then echo "Invalid floating-point number: '-' not allowed \ after decimal point" >&2 return 1 fi if [ "$fractionalPart" != "" ]; then if ! validint "$fractionalPart" "0" ""; then return 1 fi fi if [ "$decimalPart" = "-" -o -z "$decimalPart" ]; then if [ -z $fractionalPart ]; then echo "Invalid floating-point format." >&2 fi fi else if [ "$fvalue" = "-" ]; then echo "Invalid floating-point format." >&2 return 1 fi if ! validint "$fvalue" "" ""; then return 1 fi fi return 0 } if validfloat $1; then echo "$1 is a valid floating-point value" fi全文完。