shell scripting question

Testing for the presence/absence of a pattern in a file, using /bin/sh:

while read a;
do
b="${a##*pattern*}";
[ "$b" = "" ];
done < file

This returns 0 if there's a match. That signal ($?) can then be used outside the loop.

However this method reads through the whole file, even if the match was found in, e.g., line 1.

Can we make it more like sed '/pattern/q' or grep -m1 "pattern"? That is, as soon as we have a match, stop.

How can we break out of the loop after the first successful match**, but still return a value that can be used outside the loop?

** Ideally, there will only ever be one match, because this script is in fact being used to prevent adding duplicate lines to a file.

How about:

patterncheck() 
{
  while read a
  do 
    case $a in 
       *$1*) return 1
    esac
  done
}

patterncheck "pattern" < file

That's exactly what I was looking for. I wanted to use case..esac.

Many thanks, Scrutinizer.

I once read something that suggested as jobs get larger, case..esac is faster than if..then. Perhaps it's faster than the [ builtin as well.