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