Bash
案例語句中的 AND 運算符
我有以下程式碼。
read -p "Enter a word: " word case $word in [aeiou]* | [AEIOU]*) echo "The word begins with a vowel." ;; [0-9]*) echo "The word begins with a digit." ;; *[0-9]) echo "The word ends with a digit." ;; [aeiou]* && [AEIOU]* && *[0-9]) echo "The word begins with vowel and ends with a digit." ;; ????) echo "You entered a four letter word." ;; *) echo "I don't know what you've entered," ;; esac
當我執行這個:
Enter a word: apple123 case2.sh: line 10: syntax error near unexpected token `&&' case2.sh: line 10: ` [aeiou]* && [AEIOU]* && *[0-9])'
看起來 case 語句不支持 AND 運算符,而且我認為上述 case 語句中的 && 運算符在邏輯上是不正確的。
我知道我們可以使用 if else 來檢查輸入是否以元音和數字開頭。但我很好奇 case 是否有像 AND 運算符這樣的內置函式。
您是正確的,因為標准定義
case
不允許在模式中使用 AND 運算符。您也正確地說“以小寫元音開頭並以大寫元音開頭”不會匹配任何內容。另請注意,您的模式和解釋以數字測試的開頭/結尾反轉 - 使用模式[0-9]*
將匹配以數字開頭的單詞,而不是以數字結尾的單詞。一種方法是將您的測試組合成相同的模式,首先是最嚴格的:
case $word in ([AaEeIiOoUu]??[0-9]) echo it is four characters long and begins with a vowel and ends with a digit;; ([AaEeIiOoUu]*[0-9]) echo it is not four characters long begins with a vowel and ends with a digit;; # ... esac
另一種(冗長!)方法是嵌套您的
case
語句,每次都建立適當的響應。它是否以元音開頭,是或否?現在,它是否以數字結尾,是或否?這會很快變得笨拙,並且維護起來很煩人。另一種方法是使用一系列
case
語句來建構適用語句的字元串(或數組);如果您想提供“負面”回饋(“單詞不以元音開頭”等),您甚至可以*
為每個模式添加包羅萬象的模式。result="" case $word in [AaEeIiOoUu]*) result="The word begins with a vowel." ;; esac case $word in [0-9]*) result="${result} The word begins with a digit." ;; esac case $word in *[0-9]) result="${result} The word ends with a digit." ;; esac case $word in ????) result="${result} You entered four characters." ;; esac printf '%s\n' "$result"
舉些例子:
$ ./go.sh Enter a word: aieee The word begins with a vowel. $ ./go.sh Enter a word: jeff42 The word ends with a digit. $ ./go.sh Enter a word: aiee The word begins with a vowel. You entered four characters. $ ./go.sh Enter a word: 9arm The word begins with a digit. You entered four characters. $ ./go.sh Enter a word: arm9 The word begins with a vowel. The word ends with a digit. You entered four characters.
或者,bash 擴展了
case
語句的語法以允許選擇多個模式,如果您以以下方式結束模式;;&
:shopt -s nocasematch case $word in [aeiou]*) echo "The word begins with a vowel." ;;& [0-9]*) echo "The word begins with a digit." ;;& *[0-9]) echo "The word ends with a digit." ;;& ????) echo "You entered four characters." ;; esac
請注意,我刪除了
*
包羅萬象的模式,因為當以這種方式通過模式時,它會匹配任何東西。Bash 還有一個名為 的 shell 選項nocasematch
,我在上面設置了它,它可以對模式進行不區分大小寫的匹配。這有助於減少冗餘——我刪除了| [AEIOU]*
模式的一部分。舉些例子:
$ ./go.sh Enter a word: aieee The word begins with a vowel. $ ./go.sh Enter a word: jeff42 The word ends with a digit. $ ./go.sh Enter a word: aiee The word begins with a vowel. You entered four characters. $ ./go.sh Enter a word: 9arm The word begins with a digit. You entered four characters. $ ./go.sh Enter a word: arm9 The word begins with a vowel. The word ends with a digit. You entered four characters.