Zsh

如何檢查 zsh 數組是否包含給定值?

  • January 5, 2022

假設我有一個非關聯數組,其定義如下

my_array=(foo bar baz)

如何檢查數組是否包含給定的字元串?我更喜歡可以在if塊的條件內使用的解決方案(例如if contains $my_array "something"; then ...)。

array=(foo bar baz foo)
pattern=f*
value=foo

if (($array[(I)$pattern])); then
 echo array contains at least one value that matches the pattern
fi

if (($array[(Ie)$value])); then
 echo value is amongst the values of the array
fi

$array[(I)foo]如果未找到,則返回最後一次出現的fooin$array和 0 的索引。e標誌是它是一個e精確匹配而不是模式匹配。

要檢查值$value文字列表中的 is,您可以將該值列表傳遞給匿名函式並在函式體中查找$valuein $@

if ()(( $@[(Ie)$value] )) foo bar baz and some more; then
 echo "It's one of those"
fi

要知道在數組中找到值的次數,您可以使用${A:*B}運算符(A也位於數組中的數組元素B):

array=(foo bar baz foo)
value=foo
search=("$value")
(){print -r $# occurrence${2+s} of $value in array} "${(@)array:*search}"

或者在數組元素上使用模式匹配:

(){print -r $# occurrence${2+s} of $value in array} "${(M@)array:#$value}"

如果您有一個數組$my_array並且想知道它是否包含字元串foo,則一種可能的測試是

[[ ${my_array[(ie)foo]} -le ${#my_array} ]]

數組元素的完整、精確值必須是foo; 它不是子字元串檢查或類似的東西。

如果要查看變數的值是否$my_string在數組中,請使用

[[ ${my_array[(ie)$my_string]} -le ${#my_array} ]]

這種(ie)語法不是很明顯。ZSH 手冊的下標標誌部分對此進行了解釋。這i部分意味著我們正在使用“反向下標”:而不是像往常一樣傳遞一個下標並獲得一個值,${my_array[1]}而是傳遞一個值並要求第一個給出該值的下標。這個下標是數字的並且從 1 開始(數組的第一個元素在索引 1 處),這與大多數程式語言使用的約定不同。ein(ie)表示我們想要精確匹配,而不需要擴展模式匹配字元,例如*.

如果在數組中未找到該值,${my_array[(ie)foo]將計算數組末尾之後的第一個索引,因此對於 3 元素數組,它將返回 4。${#my_array}給出數組最後一個元素的索引,所以如果前者小於或等於後者,則給定值存在於數組中的某處。如果要檢查給定值是否不在數組中,請將“小於或等於”更改為“大於”:

[[ ${my_array[(ie)foo]} -gt ${#my_array} ]]

引用自:https://unix.stackexchange.com/questions/411304