Terry Todd asked,
| Is there a way to use procmail or any other commands piped together
| to context grep through a large mail file coming from stdin? I have
| used split to chop them up but it would be so much nicer if I could
| just grep out the entire message based on "^From: blah(_at_)blah" or
| "^Subject: blah blah" that I wanted to keep and throw the rest away.
Absolutely. If the input contains one message,
procmail < input
If it contains two or more messages,
formail -s procmail < input
or, if there is not always a blank line between the end of one message and
the start of the next,
formail -es procmail < input
If you need to use a different rcfile from ~/.procmailrc, name it on the
command line [formail -es procmail .specialrcfile < input, for example].
The major caution is that the rcfile should not tell procmail to append to
that same input (nor should that input be $DEFAULT or $ORGMAIL); otherwise
procmail will keep finding new messages at the end and never stop. To
prevent that, do one of these:
1. mv the input file to a name that the rcfile doesn't use (and also is not
$DEFAULT or $ORGMAIL);
2. find the number of messages in the input file first and use that as a
numeric argument to formail (say there are 32 messages; then make it
formail -32es procmail < input); two ways to find that out are
a. grep -c '^From ' input
b. FILENO=1 formail -es printenv FILENO < input | tail -1
(The latter looks messier but it won't be fooled by a body line beginning
with "From " that is protected by a Content-Length: header instead of being
escaped with a greater-than sign.) Then formail will stop after that many
messages; or
3. include some loop detection, such as an X-Loop: header or an ID cache, and
throw out any message that is going back for seconds.