Linux Shell Script - String Comparison with Wildcards

Linux Shell Script - String Comparison with wildcards

When using == or != in bash you can write:

if [[ $t1 == *"$t2"* ]]; then
echo "$t1 and $t2 are equal"
fi

Note that the asterisks go on the outside of the quotes and that the wildcard pattern must be on the right.

For /bin/sh, the = operator is for equality only, not pattern matching. You can use case for pattern matching though:

case "$t1" in
*"$t2"*) echo t1 contains t2 ;;
*) echo t1 does not contain t2 ;;
esac

If you're specifically targeting Linux, I would assume the presence of /bin/bash.

Comparing a variable to a string using wildcards

Right way to do that is as follows:

for dir in /opt/srv001/app/sam/trazas/*$v_fecha*; do
if [[ "$dir" != *"logdia"* ]]; then
echo "Do stuff Here"
fi
done
  1. While comparing using glob patterns keep glob pattern outside quotes.
  2. Avoid parsing ls's output.

Compare string with wildcard - ignoring case

You have a few options.

Match both manually:

if [[ $str == [aA]* ]]; then

Use nocasematch:

shopt -s nocasematch
if [[ $str == A* ]]; then

As Tom Fenech points out with bash 4+ (I believe) you can also use the new case modifying Parameter Expansions:

# For lower-casing
if [[ ${str,,} = a* ]]; then

# For upper-casing
if [[ ${str^^} = A* ]]; then

Compare wildcard string inside bash awk command

Awk doesn't have the glob (wildcard) syntax you're looking for, but you can convert your pattern to a regular expression and match that using the ~ operator:

if ($i ~ /^redis-/)

Regular expressions are more capable than shell globs - any glob pattern can be expressed as a regexp (but not vice versa).

bash wildcard with variables inside an if statement

In the reference manual, section Conditional Constructs, you will read, for the documentation of [[ ... ]]:

When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described below in Pattern Matching, as if the extglob shell option were enabled.

(emphasize is mine).

So you need to put your glob pattern to the right of the == operator:

if [[ $str == "$substr"* ]]; then

Note that the left-hand side needs not be quoted, but the part $substr of the right-hand side needs to be quoted, in case it contains glob characters like *, ?, [...], +(...), etc.

Bash - Comparing a string to an array that contains wildcards?


  • FILETYPES=("DBG" "MSG" "OUT" "output*.txt") First of all, avoid ALL_CAPS variable names except if these are meant as global environment variables.
  • "output*.txt": is ok as a globing pattern, for bash test [[ $variable == output*.txt ]] for example. But for Regex matching it needs a different syntax like [[ $variable =~ output.*\.txt ]]
  • "${FILETYPES[*]}": Expanding this array into a single_string was mostly a good approach, but it needs clever use of the IFS environment variable to help it expands into a Regex. Something like IFS='|' regex_fragment="(${array[*]})", so that each array entry will be expanded, separated by a pipe | and enclosed in parenthesis as (entry1|entry2|...).

Here is an implementation you could use:

textscript.sh

#!/usr/bin/env bash

extensions_regexes=("DBG" "MSG" "OUT" "output.*\.txt")

# Expands the extensions regexes into a proper regex string
IFS='|' regex=".*\.(${extensions_regexes[*]})"

# Prints the regex for debug purposes
printf %s\\n "$regex"

# Iterate all filenames passed as argument to the script
for filename; do

# Compare the filename with the regex
if [[ $filename =~ $regex ]]; then
printf 'file found: %s \n' "$filename"
fi

done

Sample usage:

$ touch foobar.MSG foobar.output.txt
$ bash testscript.sh *
.*\.(DBG|MSG|OUT|output.*\.txt)
file found: foobar.MSG
file found: foobar.output.txt


Related Topics



Leave a reply



Submit