在Bash中,测试数组是否包含某个值的最简单方法是什么?
当前回答
另一个没有函数的代码:
(for e in "${array[@]}"; do [[ "$e" == "searched_item" ]] && exit 0; done) && echo "found" || echo "not found"
谢谢@Qwerty关于空格的提示!
对应的功能:
find_in_array() {
local word=$1
shift
for e in "$@"; do [[ "$e" == "$word" ]] && return 0; done
return 1
}
例子:
some_words=( these are some words )
find_in_array word "${some_words[@]}" || echo "expected missing! since words != word"
其他回答
有点晚了,但你可以用这个:
#!/bin/bash
# isPicture.sh
FILE=$1
FNAME=$(basename "$FILE") # Filename, without directory
EXT="${FNAME##*.}" # Extension
FORMATS=(jpeg JPEG jpg JPG png PNG gif GIF svg SVG tiff TIFF)
NOEXT=( ${FORMATS[@]/$EXT} ) # Formats without the extension of the input file
# If it is a valid extension, then it should be removed from ${NOEXT},
#+making the lengths inequal.
if ! [ ${#NOEXT[@]} != ${#FORMATS[@]} ]; then
echo "The extension '"$EXT"' is not a valid image extension."
exit
fi
$ myarray=(one two three)
$ case "${myarray[@]}" in *"two"*) echo "found" ;; esac
found
如果你需要性能,你不希望每次搜索时都要遍历整个数组。
在这种情况下,您可以创建一个表示该数组索引的关联数组(哈希表或字典)。也就是说,它将每个数组元素映射到它在数组中的索引:
make_index () {
local index_name=$1
shift
local -a value_array=("$@")
local i
# -A means associative array, -g means create a global variable:
declare -g -A ${index_name}
for i in "${!value_array[@]}"; do
eval ${index_name}["${value_array[$i]}"]=$i
done
}
然后你可以这样使用它:
myarray=('a a' 'b b' 'c c')
make_index myarray_index "${myarray[@]}"
并像这样测试成员:
member="b b"
# the "|| echo NOT FOUND" below is needed if you're using "set -e"
test "${myarray_index[$member]}" && echo FOUND || echo NOT FOUND
或者:
if [ "${myarray_index[$member]}" ]; then
echo FOUND
fi
请注意,即使在测试值或数组值中存在空格,该解决方案也能正确执行。
作为奖励,您还可以通过以下方式获得数组中值的索引:
echo "<< ${myarray_index[$member]} >> is the index of $member"
下面的代码检查给定值是否在数组中,并返回其从零开始的偏移量:
A=("one" "two" "three four")
VALUE="two"
if [[ "$(declare -p A)" =~ '['([0-9]+)']="'$VALUE'"' ]];then
echo "Found $VALUE at offset ${BASH_REMATCH[1]}"
else
echo "Couldn't find $VALUE"
fi
匹配是在完整的值上完成的,因此设置VALUE="three"将不匹配。
我有这样的情况,我必须检查一个ID是否包含在另一个脚本/命令生成的ID列表中。 我的工作如下:
# the ID I was looking for
ID=1
# somehow generated list of IDs
LIST=$( <some script that generates lines with IDs> )
# list is curiously concatenated with a single space character
LIST=" $LIST "
# grep for exact match, boundaries are marked as space
# would therefore not reliably work for values containing a space
# return the count with "-c"
ISIN=$(echo $LIST | grep -F " $ID " -c)
# do your check (e. g. 0 for nothing found, everything greater than 0 means found)
if [ ISIN -eq 0 ]; then
echo "not found"
fi
# etc.
你也可以像这样缩短/压缩它:
if [ $(echo " $( <script call> ) " | grep -F " $ID " -c) -eq 0 ]; then
echo "not found"
fi
在我的例子中,我正在运行jq来过滤一些JSON的ID列表,然后必须检查我的ID是否在这个列表中,这对我来说是最好的。 它不适用于手动创建的LIST=("1" "2" "4")类型的数组,而是用于换行分隔的脚本输出。
附言:不能评论一个答案,因为我是相对较新的…