Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if an element is present in a Bash array [duplicate]

I was wondering if there is an efficient way to check if an element is present within an array in Bash? I am looking for something similar to what I can do in Python, like:

arr = ['a','b','c','d']  if 'd' in arr:     do your thing else:     do something 

I've seen solutions using associative array for bash for Bash 4+, but I am wondering if there is another solution out there.

Please understand that I know the trivial solution is to iterate in the array, but I don't want that.

like image 211
QuantumLicht Avatar asked Jan 16 '13 19:01

QuantumLicht


People also ask

How do you check if an array contains a duplicate value?

To check if an array contains duplicates:Use the Array. some() method to iterate over the array. Check if the index of the first occurrence of the current value is NOT equal to the index of its last occurrence. If the condition is met, then the array contains duplicates.

What does =~ mean in bash?

A regular expression matching sign, the =~ operator, is used to identify regular expressions. Perl has a similar operator for regular expression corresponding, which stimulated this operator.

What is $@ in bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.


2 Answers

You could do:

if [[ " ${arr[*]} " == *" d "* ]]; then     echo "arr contains d" fi 

This will give false positives for example if you look for "a b" -- that substring is in the joined string but not as an array element. This dilemma will occur for whatever delimiter you choose.

The safest way is to loop over the array until you find the element:

array_contains () {     local seeking=$1; shift     local in=1     for element; do         if [[ $element == "$seeking" ]]; then             in=0             break         fi     done     return $in }  arr=(a b c "d e" f g) array_contains "a b" "${arr[@]}" && echo yes || echo no    # no array_contains "d e" "${arr[@]}" && echo yes || echo no    # yes 

Here's a "cleaner" version where you just pass the array name, not all its elements

array_contains2 () {      local array="$1[@]"     local seeking=$2     local in=1     for element in "${!array}"; do         if [[ $element == "$seeking" ]]; then             in=0             break         fi     done     return $in }  array_contains2 arr "a b"  && echo yes || echo no    # no array_contains2 arr "d e"  && echo yes || echo no    # yes 

For associative arrays, there's a very tidy way to test if the array contains a given key: The -v operator

$ declare -A arr=( [foo]=bar [baz]=qux ) $ [[ -v arr[foo] ]] && echo yes || echo no yes $ [[ -v arr[bar] ]] && echo yes || echo no no 

See 6.4 Bash Conditional Expressions in the manual.

like image 92
glenn jackman Avatar answered Oct 13 '22 06:10

glenn jackman


Obvious caveats aside, if your array was actually like the one above, you could do

if [[ ${arr[*]} =~ d ]] then   do your thing else   do something fi 
like image 32
Zombo Avatar answered Oct 13 '22 04:10

Zombo