where file2 contains your search patterns. First, all the contents of file2 are stored in the array "a". When the file1 is processed, every line is checked against the array, and printed only if is not present.

5000 is just my guess at "reasonably short", as grep finds the first match and outputs it together with the next 5000 lines (the file doesn't need to have that many). If you don't want the match itself you'll need to cut it off, e.g.

grep -A5000 -m1 -e 'dog 123 4335' animals.txt | tail -n+2

If you do not want the first, but the last match as delimiter you could use this:

tac animals.txt | sed -e '/dog 123 4335/q' | tac

This line reads animals.txt in reverse order of lines and outputs up to and including the line with dog 123 4335 and then reverses again to restore proper order.

Again, if you don't need the match in the result, append tail. (You could also complicate the sed expression to discard its buffer before quitting.)