2023年新答案
很不幸,我不确定在哪个版本的bash中添加了双方括号,但目前更好的版本是:
array=([12]="red" [51]="black" [129]="blue")
for i in 10 12 30 {50..52} {128..131};do
if [[ -v array[i] ]];then
echo "Variable 'array[$i]' is defined"
else
echo "Variable 'array[$i]' not exist"
fi
done
Variable 'array[10]' not exist
Variable 'array[12]' is defined
Variable 'array[30]' not exist
Variable 'array[50]' not exist
Variable 'array[51]' is defined
Variable 'array[52]' not exist
Variable 'array[128]' not exist
Variable 'array[129]' is defined
Variable 'array[130]' not exist
Variable 'array[131]' not exist
请注意测试行中使用的双方括号(并删除引号)。
同样,但使用关联数组的方式:
这与关联数组的使用方式相同:
declare -A aArray=([foo]="bar" [bar]="baz" [baz]=$'Hello world\041')
for i in alpha bar baz dummy foo test;do
if [[ -v aArray[$i] ]];then
echo "Variable 'aArray[$i]' is defined"
else
echo "Variable 'aArray[$i]' not exist"
fi
done
Variable 'aArray[alpha]' not exist
Variable 'aArray[bar]' is defined
Variable 'aArray[baz]' is defined
Variable 'aArray[dummy]' not exist
Variable 'aArray[foo]' is defined
Variable 'aArray[test]' not exist
有一点不同:在常规数组中,方括号(
[i]
)中的变量是整数,所以不需要美元符号(
$
),但对于关联数组,由于键是一个单词,需要使用美元符号(
[$i]
)!
2021年以前的版本
从bash的4.2版本(及更高版本)开始,内置的test
命令有一个新的-v
选项。
从4.3版本开始,这个测试可以访问数组的元素。
array=([12]="red" [51]="black" [129]="blue")
for i in 10 12 30 {50..52} {128..131};do
if [ -v 'array[i]' ];then
echo "Variable 'array[$i]' is defined"
else
echo "Variable 'array[$i]' not exist"
fi
done
注意:关于
ssc的评论,我在-v测试中使用了
单引号引用
'array[i]'
,以满足shellcheck的错误
SC2208。这在这里似乎并不是真正需要的,因为
array[i]
中没有通配符字符,无论如何...
旧版bash V4.2之前的答案
不幸的是,bash没有办法区分空变量和未定义变量。
但有一些方法:
$ array=()
$ array[12]="red"
$ array[51]="black"
$ array[129]="blue"
$ echo ${array[@]}
red black blue
$ echo ${!array[@]}
12 51 129
$ echo "${#array[@]}"
3
$ printf "%s\n" ${!array[@]}|grep -q ^51$ && echo 51 exist
51 exist
$ printf "%s\n" ${!array[@]}|grep -q ^52$ && echo 52 exist
(不给答案)
(对于关联数组,你可以使用相同的方法:)
$ unset array
$ declare -A array
$ array["key1"]="red"
$ array["key2"]="black"
$ array["key3"]="blue"
$ echo ${array[@]}
blue black red
$ echo ${!array[@]}
key3 key2 key1
$ echo ${#array[@]}
3
$ set | grep ^array=
array=([key3]="blue" [key2]="black" [key1]="red" )
$ printf "%s\n" ${!array[@]}|grep -q ^key2$ && echo key2 exist || echo key2 not exist
key2 exist
$ printf "%s\n" ${!array[@]}|grep -q ^key5$ && echo key5 exist || echo key5 not exist
key5 not exist
你可以在不使用外部工具(没有printf | grep,纯粹的bash)的情况下完成这项工作,为什么不构建一个名为checkIfExist()的新的bash函数呢?
$ checkIfExist() {
eval 'local keys=${!'$1'[@]}';
eval "case '$2' in
${keys// /|}) return 0 ;;
* ) return 1 ;;
esac";
}
$ checkIfExist array key2 && echo exist || echo don\'t
exist
$ checkIfExist array key5 && echo exist || echo don\'t
don't
或者甚至创建一个新的
getIfExist bash函数,如果所需值不存在,则返回所需值并以错误结果代码退出:
$ getIfExist() {
eval 'local keys=${!'$1'[@]}';
eval "case '$2' in
${keys// /|}) echo \${$1[$2]};return 0 ;;
* ) return 1 ;;
esac";
}
$ getIfExist array key1
red
$ echo $?
0
$
$ array["key4"]=""
$ getIfExist array key4
$ echo $?
0
$ getIfExist array key5
$ echo $?
1
+abc
,则[ ${array[key]} ]
将在元素确实被设置但为空值时评估为 false,因此它实际上测试的是值的非空而不是键的存在。 - musiphil[[ ${array[key]+Y} ]] && echo Y || echo N
- Thamme Gowdaeval
是有害的!!试试这个例子:exists foo in 'O};cat /etc/passwd;echo -e \\e[5m'
。 - F. Hauri - Give Up GitHub