bash 检查数组中的索引或键的最简单方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13219634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Easiest way to check for an index or a key in an array?
提问by Luca Borrione
Using:
使用:
set -o nounset
1) Having an indexed array like:
1)有一个索引数组,如:
myArray=( "red" "black" "blue" )
What is the shortest way to check if element 1 is set?
I sometimes use the following:
检查元素 1 是否设置的最短方法是什么?
我有时会使用以下内容:
test "${#myArray[@]}" -gt "1" && echo "1 exists" || echo "1 doesn't exist"
I would like to know if there's a preferred one.
2) How to deal with non-consecutive indexes?
我想知道是否有首选的。
2)如何处理非连续索引?
myArray=()
myArray[12]="red"
myArray[51]="black"
myArray[129]="blue"
How to quick check that '51' is already set for example?
3) How to deal with associative arrays?
例如,如何快速检查“51”是否已设置?
3)如何处理关联数组?
declare -A myArray
myArray["key1"]="red"
myArray["key2"]="black"
myArray["key3"]="blue"
How to quick check that 'key2' is already used for example?
Thanks
例如,如何快速检查“key2”是否已被使用?
谢谢
EDITED
The simplest way seems to me:
编辑
在我看来最简单的方法:
if test "${myArray['key_or_index']+isset}"
then
echo "yes"
else
echo "no"
fi;
This works for both indexed and associative arrays. No errors shown with set -o nounset.
Thanks to doubleDown for the headup.
这适用于索引数组和关联数组。set -o nounset 没有显示错误。
感谢 doubleDown 的抬头。
回答by doubleDown
To check if the element is set (applies to both indexed and associative array)
检查元素是否已设置(适用于索引数组和关联数组)
[ ${array[key]+abc} ] && echo "exists"
Basically what ${array[key]+abc}
does is
基本上,${array[key]+abc}
做的是
- if
array[key]
is set, returnabc
- if
array[key]
is not set, return nothing
- 如果
array[key]
设置,返回abc
- 如果
array[key]
未设置,则不返回任何内容
参考:
See Parameter Expansionin Bash manual and the little note
if the colon is omitted, the operator tests only for existence [of parameter]
This answer is actually adapted from the answers for this SO question: How to tell if a string is not defined in a bash shell script?
请参阅Bash 手册中的参数扩展和小注释
如果省略冒号,则运算符仅测试 [of parameter]是否存在
这个答案实际上改编自这个问题的答案:如何判断字符串是否未在 bash shell 脚本中定义?
A wrapper function:
一个包装函数:
exists(){
if [ "" != in ]; then
echo "Incorrect usage."
echo "Correct usage: exists {key} in {array}"
return
fi
eval '[ ${''[]+muahaha} ]'
}
For example
例如
if ! exists key in array; then echo "No such array element"; fi
回答by Vineet
From man bash, conditional expressions:
从man bash,条件表达式:
-v varname
True if the shell variable varname is set (has been assigned a value).
example:
例子:
declare -A foo
foo[bar]="this is bar"
foo[baz]=""
if [[ -v "foo[bar]" ]] ; then
echo "foo[bar] is set"
fi
if [[ -v "foo[baz]" ]] ; then
echo "foo[baz] is set"
fi
if [[ -v "foo[quux]" ]] ; then
echo "foo[quux] is set"
fi
This will show that both foo[bar] and foo[baz] are set (even though the latter is set to an empty value) and foo[quux] is not.
这将显示 foo[bar] 和 foo[baz] 都已设置(即使后者设置为空值)而 foo[quux] 未设置。
回答by F. Hauri
New answer
新答案
From version 4.2 of bash(and newer), there is a new -v
option to built-in test
command.
从bash4.2 版(和更新版本)开始,-v
内置test
命令有一个新选项 。
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
This work with associative arraysin same way:
这以相同的方式与关联数组一起工作:
declare -A aArray=([foo]="bar" [bar]="baz" [baz]=$'Hello world1')
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
With a little difference:
In regular arrays, variable between brackets ([i]
) is integer, so dollar symbol ($
) is not required, but for associative array, as keyis a word, $
is required ([$i]
)!
有一点区别:
在常规数组中,括号 ( [i]
)之间的变量是整数,因此$
不需要美元符号 ( ),但对于关联数组,由于key是一个单词,$
因此需要 ( [$i]
)!
Old answer for bashprior to V4.2
V4.2 之前的bash旧答案
Unfortunately, bash give no way to make difference betwen emptyand undefinedvariable.
不幸的是,bash 无法区分空变量和未定义变量。
But there is some ways:
但是有一些方法:
$ 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
(give no answer)
(不回答)
And for associative array, you could use the same:
对于关联数组,您可以使用相同的:
$ 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
You could do the job without the need of externals tools (no printf|grep as pure bash), and why not, build checkIfExist()as a new bash function:
你可以在不需要外部工具的情况下完成这项工作(没有 printf|grep 作为纯 bash),为什么不,将checkIfExist()构建为一个新的 bash 函数:
$ checkIfExist() {
eval 'local keys=${!''[@]}';
eval "case '' 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
or even create a new getIfExistbash function that return the desired value and exit with false result-code if desired value not exist:
或者甚至创建一个新的getIfExistbash 函数,该函数返回所需的值,如果所需的值不存在,则以 false 结果代码退出:
$ getIfExist() {
eval 'local keys=${!''[@]}';
eval "case '' in
${keys// /|}) echo ${[]};return 0 ;;
* ) return 1 ;;
esac";
}
$ getIfExist array key1
red
$ echo $?
0
$ # now with an empty defined value
$ array["key4"]=""
$ getIfExist array key4
$ echo $?
0
$ getIfExist array key5
$ echo $?
1
回答by gdoubleod
tested in bash 4.3.39(1)-release
在 bash 4.3.39(1)-release 中测试
declare -A fmap
fmap['foo']="boo"
key='foo'
# should echo foo is set to 'boo'
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
key='blah'
# should echo blah is unset in fmap
if [[ -z "${fmap[${key}]}" ]]; then echo "$key is unset in fmap"; else echo "${key} is set to '${fmap[${key}]}'"; fi
回答by sjas
This is the easiest way I found for scripts.
这是我为脚本找到的最简单的方法。
<search>
is the string you want to find, ASSOC_ARRAY
the name of the variable holding your associative array.
<search>
是您要查找的字符串,ASSOC_ARRAY
即保存关联数组的变量的名称。
Dependign on what you want to achieve:
取决于您想要实现的目标:
key exists:
键存在:
if grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key is present; fi
key exists not:
键不存在:
if ! grep -qe "<search>" <(echo "${!ASSOC_ARRAY[@]}"); then echo key not present; fi
value exists:
值存在:
if grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value is present; fi
value exists not:
值不存在:
if ! grep -qe "<search>" <(echo "${ASSOC_ARRAY[@]}"); then echo value not present; fi
回答by Lucas Stad
I wrote a function to check if a key exists in an array in Bash:
我编写了一个函数来检查 Bash 中的数组中是否存在一个键:
# Check if array key exists
# Usage: array_key_exists $array_name $key
# Returns: 0 = key exists, 1 = key does NOT exist
function array_key_exists() {
local _array_name=""
local _key=""
local _cmd='echo ${!'$_array_name'[@]}'
local _array_keys=($(eval $_cmd))
local _key_exists=$(echo " ${_array_keys[@]} " | grep " $_key " &>/dev/null; echo $?)
[[ "$_key_exists" = "0" ]] && return 0 || return 1
}
Example
例子
declare -A my_array
my_array['foo']="bar"
if [[ "$(array_key_exists 'my_array' 'foo'; echo $?)" = "0" ]]; then
echo "OK"
else
echo "ERROR"
fi
Tested with GNU bash, version 4.1.5(1)-release (i486-pc-linux-gnu)
使用 GNU bash 测试,版本 4.1.5(1)-release (i486-pc-linux-gnu)
回答by GuyPaddock
What about a -z
test and the :-
operator?
怎么样一个-z
测试和:-
运营商?
For example, this script:
例如,这个脚本:
#!/usr/bin/env bash
set -e
set -u
declare -A sample
sample["ABC"]=2
sample["DEF"]=3
if [[ ! -z "${sample['ABC']:-}" ]]; then
echo "ABC is set"
fi
if [[ ! -z "${sample['DEF']:-}" ]]; then
echo "DEF is set"
fi
if [[ ! -z "${sample['GHI']:-}" ]]; then
echo "GHI is set"
fi
Prints:
印刷:
ABC is set
DEF is set