Home > Software engineering >  bash check if value exist in array , it seems single(i) is trying to match with double digit numeric
bash check if value exist in array , it seems single(i) is trying to match with double digit numeric

Time:10-26

it seems single(i) is trying to match with double digit numeric (10 is one of of the value in array)

STATE 1

abc@xyz $ i=1
abc@xyz $ allStatus=(2 3 4 5 6 7 8 9 10)


abc@xyz $ if [[ ! ${allStatus[@]} =~ $i ]]
> then
> echo OK
> fi

STATE 2


abc@xyz $ i=2
abc@xyz $ allStatus=(1 3 4 5 6 7 8 9 10)
abc@xyz $  
abc@xyz $ if [[ ! ${allStatus[@]} =~ $i ]]
> then
> echo OK
> fi
OK
abc@xyz $

all i want is, STATE 1 should echo/print OK

CodePudding user response:

That's because the value after =~ is interpreted as a regular expression, and the string 10 matches the regular expression 1.

You need to check that there's a space or string start before the value and space or string end after the value:

[[ ${arr[@]} =~ ( |^)$i( |$) ]]

This can still fail if the value a 1 b belongs to the array:

foStatus=(2 3 'a 1 b')

The correct way is to iterate over the values and check for equality:

arr=(2 3 1 4 9 10 'a 1 b')
i=1
for v in "${arr[@]}" ; do
   if [[ $v == "$i" ]] ; then
       echo OK
   fi
done

CodePudding user response:

Since you are checking a numeric status exist, you can use a sparse array index and do:

#!/usr/bin/env bash

i=2
allStatus=([1]=1 [3]=1 [4]=1 [5]=1 [6]=1 [7]=1 [8]=1 [9]=1 [10]=1)

if ((allStatus[i])); then
  echo OK
fi

You can also create a bit-field and check bit is on:

#!/usr/bin/env bash

i=2
allStatus=(1 3 4 5 6 7 8 9 10)
# Set all bits corresponding to status by expanding array elements
# into the arithmetic expression:
# 0 | 1 << element1 | 1 << element2 |...
allStatusBin=$((0${allStatus[@]/#/|1<<}))

# Or set it directly in binary
#allStatusBin=$((2#11111111010))

if ((1<<i&allStatusBin)); then
  echo OK
fi
  •  Tags:  
  • bash
  • Related