Reputation: 25
I'm trying to write a bash code which should get a variable and search within multiple arrays. For example:
$var = site.com
And my arrays are:
array1=(test world myword something bla my.site.com)
array=(google facebook stackoverflow site.com)
array=(music eating video site.com.dev)
The code that I'm trying to run and unfortunately not working is:
#!/bin/bash
if [[ ${array1[*]} =~ "$var" ]]; then
echo "it's array1"
elif [[ ${array2[*]} =~ "$var" ]]; then
echo "it's array2"
elif [[ ${array3[*]} =~ "$var" ]]; then
echo "it's array3"
fi
The problem here is that it even it return the same array for "site.com", "my.site.com" and "site.com.dev".
What's missing here and how I should write it properly?
Upvotes: 1
Views: 1332
Reputation: 295383
=~
is an unanchored regex -- when the right side is quoted, it becomes a substring search. ${array[*]}
assembles a string by combining all the entries in your array with the first character in IFS
(a space by default) between them. Thus, [[ ${array[*]} =~ "$var" ]]
is flattening your array into a string, and doing a substring search on that string.
site.com
is a substring of my.site.com
and of site.com.dev
, so it's expected for it to match.
If you want an efficient, exact-match-only search, invert your arrays to be associative rather than numerically-indexed, and do a key lookup for each.
That is:
#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Needs bash 4.0 or newer" >&2; exit 1;; esac
var=site.com
declare -A array1=( [test]=1 [world]=1 [myword]=1 [something]=1 [my.site.com]=1 )
declare -A array2=( [google]=1 [facebook]=1 [stackoverflow]=1 [site.com]=1 )
declare -A array3=( [music]=1 [eating]=1 [video]=1 [site.com.dev]=1 )
if [[ ${array1["$var"]} ]]; then echo "It's array1"
elif [[ ${array2["$var"]} ]]; then echo "It's array2"
elif [[ ${array3["$var"]} ]]; then echo "It's array3"
else echo "Not found"
fi
Upvotes: 3