Aljaz
Aljaz

Reputation: 303

Compare strings if contains in bash

I am trying to implement bash script that is reading from error log file and comparing strings with exceptions.

I am trying to compare it with if

error="[*] Text Text @ level 4: 'Some text' [parent = 'Not found'] "
exception="'Not found'"
if [[ "${error}" == *"${exception}"* ]]; then                                   
    echo "Yes it contains!"
fi

In this case I would expect the script to return "Yes it contains!", but it doesn't work as I expected. But it is true that my logs contain special character as well, anyone knows how should I handle that and compare it?


For me my if also works, but I might have something wrong in my nested loop. I am running the script in following process.

  1. I have file with errors called mylogfile.txt:

    [*] Text Text @ level 4: 'Some text' [parent = 'Not found']
    
  2. Then I have another file where I have exceptions inserted exception.txt:

    'Not found'
    
  3. I do a loop over both files to see if I find anything:

    while IFS='' read -r line || [ -n "$line" ]; do 
        exception="$line"                       
        while IFS='' read -r line || [ -n "$line" ]; do
            err="$line"                                                 
            if [[ "${err}" == *"${exception}"* ]]; then                                 
                echo "Yes it contains!"
            fi                  
        done < "mylogfile.txt"                  
    done < "exception.txt"
    

Upvotes: 2

Views: 149

Answers (2)

John Kugelman
John Kugelman

Reputation: 361585

I don't see anything wrong with your script, and it works when I run it.

That said, looping over files line by line in a shell script is a code smell. Sometimes it's necessary, but often you can trick some command or another into doing the hard work for you. When searching through files, think grep. In this case, you can actually get rid of both loops with a single grep!

$ grep -f exception.txt mylogfile.txt
[*] Text Text @ level 4: 'Some text' [parent = 'Not found']

To use it in an if statement, add -q to suppress its normal output and just check the exit code:

if grep -qf exception.txt mylogfile.txt; then
    echo "Yes, it's contained!"
fi

From the grep(1) man page:

-f FILE, --file=FILE

  • Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing.

-q, --quiet, --silent

  • Quiet; do not write anything to standard output. Exit immediately with zero status if any match is found, even if an error was detected.

Upvotes: 2

Sonny
Sonny

Reputation: 3183

Use grep if you want exact match

if grep -q "$exception" <<< "$error"; then
    echo "Yes it contains!"
fi

Use -i switch to ignore case

Upvotes: 1

Related Questions