Match One of Several Words with grep -E Alternation
Match one of several words with the bar operator in grep -E, and put the alternatives in parentheses before adding anchors. Otherwise ^ and $ bind to one side only.
You want lines that are exactly cat or dog, and a pattern with a bar and anchors returns more than that.
printf '%s\n' cat dog catalog dogma bobcat > words.txt
echo "--- cat|dog"; grep -E 'cat|dog' words.txt
echo "--- ^cat|dog$"; grep -E '^cat|dog$' words.txt
echo "--- ^(cat|dog)$"; grep -E '^(cat|dog)$' words.txt
echo "--- -x does the anchoring"; grep -Ex 'cat|dog' words.txt--- cat|dog
cat
dog
catalog
dogma
bobcat
--- ^cat|dog$
cat
dog
catalog
--- ^(cat|dog)$
cat
dog
--- -x does the anchoring
cat
dogThe alternation operator has the lowest precedence, so ^cat|dog$ means "starts with cat" or "ends with dog", and the run returned cat, dog and catalog. Wrapping the alternatives, as in ^(cat|dog)$, applies the anchors to both and returned just cat and dog. grep -Ex does the same by requiring the whole line to match. See Basic vs Extended in the grep manual.
In basic regular expressions the bar is a GNU extension that needs an escape, so use -E for portability. Order can matter in engines like Perl's, which take the first alternative that works and not the longest one; the POSIX engines in grep -E take the longest.