我试图检查数组是否包含值,我发现检查Bash数组是否包含值
它不适合我,这是因为我决定删除引号周围的空格,像这样:
words=(aa bb cc)
[[ " ${words[@]} " =~ " a " ]] && echo "YES" || echo "NO"; # This is the real answer, and it works
------
[[ "${words[@]}" =~ "a" ]] && echo "YES" || echo "NO"; # This does not work. Why???
- 用空格包围它们和不用空格包围它们有什么区别?
为了我的好奇心。在我提到的上一个问题中,一些答案/评论如下:
${array[*]}
和其他${array[@]}
- 他们是否都"iterate"以同样的方式通过循环吗?
[[ string =~ regex ]]
检查regex
是否匹配string
的子字符串。操作符不像for entry in "${words[@]}"
那样遍历数组条目。它甚至不能处理数组。
[[ " ${words[@]} " =~ " a " ]]
只是一个hack用于查找数组元素。数组被转换成一个字符串,其中所有数组项都被空格包围。然后,使用字符串搜索来搜索元素。只有在数组项本身不包含空格的情况下,才能可靠地工作。
关于${array[*]}
和${array[@]}
的区别,请参阅bash的手册:
如果单词是双引号,
${name[*]}
展开成一个单词每个数组成员的值由IFS变量的第一个字符分隔[默认=空格],${name[@]}
扩展每个元素将名称转换为单独的单词.
所以在这种情况下,*
将是写[[ " ${words[*]} " =~ " a " ]]
的逻辑方式,因为它相当于[[ " aa bb cc " =~ " a " ]]
。@
在这里也起作用有点奇怪,因为[[ " aa" "bb" "cc " =~ " a " ]]
给出了语法错误。Bash容忍[[
中的@
被误用可能是一个未记录的"特性"。与[[
中禁用的分词功能相关。对于基本的POSIX测试命令[
,*
和@
之间的差异与预期的一样,这意味着a=("x" "=" "y"); [ "${a[@]}" ]
失败,因为x != y。