如何测试某项是否在bash数组中?


15

帮助一个简单的脚本

#!/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(我使用数组),然后简单地给我,是存在还是不存在。我不知道如何比较具有单个变量的数组。


4
在哪里array1工作?
tachomi

Answers:


17

使用另一种类型的数组:请使用关联数组,而不要使用整数索引数组,因此将要检查的是键(索引)。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

14

直接的方法是使用循环进行迭代:

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

[[ a == aaa ]]是错误的,但是匹配aaa否?
吉尔斯·奎诺

因此,应该通知OP,他必须注意值是否可以包含特殊字符,例如[ ]:字符类(
全局

[[ ]]对于您所说的内容,我认为bash中的=和==没有区别。你测试了吗?
吉尔斯·奎诺

2

zsh

array1=(
  prova1
  prova2
  slack64
)

a=slack64

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

2

此函数适用于关联数组。

我们可以使用此功能执行以下操作之一:

-检查数组是否具有特定键-----------------> inArray“ myKey” $ {!myArray [@]}“

-检查数组是否包含特定值---------> inArray“ myValue”“ $ {myArray [@]}”

function inArray # ( keyOrValue, arrayKeysOrValues ) 
{
  local e
  for e in "${@:2}"; do 
    [[ "$e" == "$1" ]] && return 0; 
  done
  return 1
}

declare -A arr
arr[doo]=55

inArray "doo" "${!arr[@]}"
echo $?     # 0 
inArray "bla" "${!arr[@]}"
echo $?     # 1 
inArray "55" "${arr[@]}"
echo $?     # 0

2

您也可以使用grep:

array1 =(prova1 prova2 slack64)
a =松弛64
if(printf'%s \ n'“ $ {array1 [@]}” | grep -xq $ a);然后
    回声“它在”
科幻

1
假设array元素不包含换行符(以及忘记引用的空白和通配符$a,而-忘记了则不以开头--)。您可以使用%s\0代替,%s\n并使用grep --null(假设是GNU grep或兼容的),因为bash变量无论如何都不能包含NUL字符。您还需要专门处理空数组的情况(因为该printf命令将打印与具有一个空元素的数组相同的内容)。还要注意,您无需在此处启动子shell。
斯特凡Chazelas

是的,它适用于简单数组,如问题中的数组。
彼得·凯特纳
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.