2016-12-02 63 views
0

我試圖創建一個退出錯誤來擴展前面的腳本。如果我輸入什麼,但現在一些什麼我迄今試圖爲:bash if for循環中的結構

sum=0 
for num in "[email protected]" 
do 
echo $num | grep -i [^0-9+-] 
if ["$?" = 1] then 
echo "Sorry, '$num' is not a number" 
fi 

sum=$((sum + num)) 
done 
echo $sum 

例如,如果我在

add 1 2 3 four five 

鍵入它會說

four 
Sorry, 'four' is not a number 
+0

目前還不清楚在所有什麼你想實現嗎?如果一個不是數字的字符串被傳遞了,你仍然把它算作一個數字。這是對的嗎?另外$? = 1是錯誤的。正確的語法是$? -eq 1,但最好使用$? -gt 0它更可靠 – m47730

+0

@ m47730可以說直接使用if命令而不是使用'$?'更好。 –

+0

@TomFenech我同意你的意見。我在說,最好使用「-gt 0」代替「-eq 1」 – m47730

回答

1

的以下部分您的代碼:

echo $num | grep -i [^0-9+-] 
if ["$?" = 1] then 

Sh烏爾德改成這樣:

if grep -q '[^0-9+-]' <<< "$num"; then 

內部測試([),空間是重要的,但沒有必要在這裏反正使用它。使用-q表示grep不生成輸出 - 退出狀態指示是否找到匹配項,因此可以直接使用if

正如評論中所提到的,可以使匹配有效整數的模式更加健壯。在this related question中顯示了檢測整數的一些好方法。例如,你可以這樣你的grep模式更改爲:

grep -qE '^[+-]?(0|[1-9][0-9]*)$' 

或使用本機的正則表達式,如最流行的這個問題的答案:

re='^[+-]?(0|[1-9][0-9]*)$' 
if [[ $num =~ $re ]]; then 
    sum=$((sum + num)) 
else 
    echo "Sorry, '$num' is not a number" 
fi 

即使這種模式是不是完美的,因爲它將以領先0 s開頭的號碼失敗,等等。

+0

,你必須在輸入中測試唯一的'-'。正則表達式會稍微複雜一些。 –

+0

@讓 - 弗朗索瓦這是一個很好的觀點,我編輯了我的答案。 –

+1

請注意,'09'會導致添加錯誤,因爲它會被解釋爲八進制。 – choroba

0

無需掏腰包。您可以使用擴展模式匹配來驗證數字格式:

#!/bin/bash 
shopt -s extglob 

sum=0 
for num in "[email protected]" ; do 
    if [[ $num != @(0|?([-+])[1-9]*([0-9])) ]] ; then 
     echo "Sorry, '$num' is not a number" 
     exit 1 
    fi 
    ((sum += num)) 
done 
echo $sum 

注意09是不允許的,因爲它會被解釋爲八進制,另外失敗:

value too great for base (error token is "09") 
+0

或者''[[$ num =〜^ [+ - ]?[0-9]]]''也許更簡單。 – SLePort

+0

@SLePort:那不符合'09'。 – choroba

+0

@SLePort:正確的正則表達式在另一個答案中。我只是想表明,即使正則表達式在這裏太強大了。 – choroba