如何检查 Bash 数组是否包含值

如何检查 Bash 数组是否包含值

帮助一个简单的脚本

#!/bin/bash

array1=(
prova1
prova2
slack64
)

a="slack64"
b="ab"

if [ $a = $b ]
then
      echo "$a = $b : a is equal to b"
else
      echo "$a = $b: a is not equal to b"
fi

这个脚本根本不起作用,我想要一个脚本来检查 slack64 是否存在于列表中(我使用数组),然后简单地告诉我,是存在,或者不存在。我不知道如何将数组与单个变量进行比较。

答案1

使用不同类型的数组:使用关联数组而不是整数索引数组,因此键(索引)就是您要检查的内容。bash-4.0或稍后需要为此。

declare -A array1=( 
 [prova1]=1  [prova2]=1  [slack64]=1
)

a=slack64
[[ -n "${array1[$a]}" ]] && printf '%s is in array\n' "$a"

在上面我们并不真正关心这些值,它们只需要非空即可。您可以通过交换键和值将索引数组“反转”为新的关联数组:

declare -a array1=( 
 prova1 prova2 slack64
)
declare -A map    # required: declare explicit associative array
for key in "${!array1[@]}"; do map[${array1[$key]}]="$key"; done  # see below

a=slack64
[[ -n "${map[$a]}" ]] && printf '%s is in array\n' "$a"

如果您有经常搜索的大型数组,这会带来回报,因为关联数组的实现比数组遍历循环的执行效果更好。但它并不适合所有用例,因为它无法处理重复项(尽管您可以使用该值作为计数器,而不是像上面那样仅使用 1),并且它无法处理空索引。

拆开上面的复杂线,来解释“反转”:

for key in "${!a[@]}"     # expand the array indexes to a list of words
do 
  map[${a[$key]}]="$key"  # exchange the value ${a[$key]} with the index $key
done

答案2

最简单的方法是使用循环进行迭代:

var=ab
for item in "${array[@]}"; do
    [[ $var == "$item" ]] && echo "$var present in the array"
done

答案3

如何检查 Bash 数组是否包含值


误报匹配

array=(a1 b1 c1 d1 ee)

[[ ${array[*]} =~ 'a' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'a1' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'e' ]] && echo 'yes' || echo 'no'
# output:
yes

[[ ${array[*]} =~ 'ee' ]] && echo 'yes' || echo 'no'
# output:
yes

完全符合

为了寻找精确匹配,您的正则表达式模式需要在值之前和之后添加额外的空格,例如(^|[[:space:]])"VALUE"($|[[:space:]])

# Exact match

array=(aa1 bc1 ac1 ed1 aee)

if [[ ${array[*]} =~ (^|[[:space:]])"a"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
No

if [[ ${array[*]} =~ (^|[[:space:]])"ac1"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

find="ac1"
if [[ ${array[*]} =~ (^|[[:space:]])"$find"($|[[:space:]]) ]]; then
    echo "Yes";
else
    echo "No";
fi
# output:
Yes

有关更多用法示例,示例来源是这里

答案4

zsh

array1=(
  prova1
  prova2
  slack64
)

a=slack64

if (( $array1[(Ie)$a] )); then
  printf '%s\n' "$a in array1"
fi

数组I下标标志用于返回匹配的最右边元素的索引$a(如果没有找到则返回0); with e,它是精确/字面匹配,而不是模式匹配。


bash

由于 bash 的数组成员不能包含 NUL 字节(与 zsh 相反),如果您有 GNUgrep或兼容版本,您始终可以这样做:

if (( ${#array1[@]} )) && printf '%s\0' "${array1[@]}" | grep -zqxFe "$a"; then
  printf '%s\n' "$a in array1"
fi

也就是说,打印 NUL 分隔的元素并要求grep快速q找到存储在中的表达式的x固定F字符串匹配项e$a这些zero 分隔记录

相关内容