咋一看,在一個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全文完。