Thursday, January 6, 2022

[SOLVED] Check if any substring is contained in an array in Bash

Issue

Suppose I have a string,

a="This is a string"

and an array,

b=("This is my" "sstring")

I want to execute an if condition if any substring of a lies in b which is true because "This is" is a substring of the first element of b.

In case of two strings I know how to check if $x is a substring of $y using,

if [[ $y == *$x* ]]; then
 #Something
fi

but since $x is an array of strings I don't know how to do it without having to explicitly loop through the array.


Solution

This might be all you need:

$ printf '%s\n' "${b[@]}" | grep -wFf <(tr ' ' $'\n' <<<"$a")
This is my

Otherwise - a shell is a tool to manipulate files/processes and sequence calls to tools. The guys who invented shell also invented awk for shell to call to manipulate text. What you're trying to do is manipulate text so there's a good chance you should be using awk instead of shell for whatever it is you're doing that this task is a part of.

$ printf '%s\n' "${b[@]}" | 
awk -v a="$a" '
    BEGIN { split(a,words) }
    { for (i in words) if (index($0,words[i])) { print; f=1; exit} }
    END { exit !f }
'
This is my

The above assumes a doesn't contain any backslashes, if it can then use this instead:

printf '%s\n' "${b[@]}" | a="$a" awk 'BEGIN{split(ENVIRON["a"],words)} ...'

If any element in b can contain newlines then:

printf '%s\0' "${b[@]}" | a="$a" awk -v RS='\0' 'BEGIN{split(ENVIRON["a"],words)} ...'


Answered By - Ed Morton