Zsh
如何檢查 zsh 數組是否包含給定值?
假設我有一個非關聯數組,其定義如下
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]
如果未找到,則返回最後一次出現的foo
in$array
和 0 的索引。e
標誌是它是一個e
精確匹配而不是模式匹配。要檢查值
$value
的文字列表中的 is,您可以將該值列表傳遞給匿名函式並在函式體中查找$value
in$@
: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 處),這與大多數程式語言使用的約定不同。e
in(ie)
表示我們想要精確匹配,而不需要擴展模式匹配字元,例如*
.如果在數組中未找到該值,
${my_array[(ie)foo]
將計算數組末尾之後的第一個索引,因此對於 3 元素數組,它將返回 4。${#my_array}
給出數組最後一個元素的索引,所以如果前者小於或等於後者,則給定值存在於數組中的某處。如果要檢查給定值是否不在數組中,請將“小於或等於”更改為“大於”:[[ ${my_array[(ie)foo]} -gt ${#my_array} ]]