Yes, for two you can first find the longest common prefix of both (here people were wondering how to do that in Bash Longest common prefix of two strings in bash), then first check whether the lines start with it and then after stripping it from both the tag and the line check whether the lines start with the rest of it.
For more than two, you need to make a trie — also known as a prefix tree https://en.wikipedia.org/wiki/Trie .
That Wikipedia article says
For the space-optimized presentation of prefix tree, see compact prefix tree.
And having longest common prefixes, that's what you're gonna have.
Since Bash doesn't have multidimensional associative arrays, you will have to either consider https://en.wikipedia.org/wiki/Trie#Implementation_strategies or embed some other scripting language, like Perl or Python — or GNU Awk (gawk
), which, unlike to standard Awk, introduces multidimensional associative arrays.
Using the optimization of Bash's associative arrays implementation
As suggested in comment, we may consider taking just the tag with a simpler regex and using it as a key for associative array which are somewhat optimized in Bash (we can investigate how well-suited for our needs in the sources:
if we know what it is delimited by — like, if we know that it is always immediately followed by a :
or something while not containing it, and using a simpler regex like:
[[ $LINE =~ ^(.*): ]] && "${DICTIONARY_OF_FUNCTIONS["${BASH_REMATCH[1]}"]}"
or Using the optimization of Bash's functions store
if all your tags are like, /[a-z][a-z0-9]+/
or otherwise accepted by Bash as function names, and delimited as in the method with Bash's associative arrays, then you can use the above method for interpolating function names, like,
function the_function_for_tag_headertag1() {
echo "hey it's the first one"
}
[[ $LINE =! ^(.*): ]] && {
func_name="the_function_for_tag_${BASH_REMATCH[1]}"
type "${func_name}" && "${func_name}"
}