real language

Bookmarking Digg Diigo DZone Earthlink Google
Windows Live LookLater Ma.gnolia Reddit Rojo StumbleUpon Technorati

Language Procmail

Score: (3.00 in 9 votes)
# "99 Bottles of Beer" for Procmail -- body filtering version
# era  Fri Jun 12 18:59:44 1998
# Reacts on incoming mail -- if the Subject: matches the regex, start looping
# This will create a large amount of mail in your inbox. You have been warned


# Might need to change PATH e.g. if it doesn't normally include the location
#  where you have formail installed

# If the incoming message matches this regex, generate a copy with a 
#  new subject line, one bottle less, and send it, too, to myself. 
#  Also change the body to reflect the new number.
#  (Other than that, this is basically the same as the looprc version)

* ^Subject:\/\<*[1-9][0-9]*\<+bottles?\<+of\<+beer\>*$
    # Store MATCH before processing it more

    # Extract string part
    * SUBJECT ?? bottles?\/\<.*

    # Extract number part and resend the message
    * SUBJECT ?? ^^\<*\/[0-9]+
    * $ $MATCH^0
    * -1^0
        # Gack, hafta put score in a "real" variable to make it useful

        # Ugliness: Precalculate the number of "one down" bottles
        #  for the last stanza of the song
        * $ $BOTTLES^0
        * -1^0
        { }
        * NEWBOTTLES ?? ^^0^^
        { NEWBOTTLES="No" }

        # Calculate whether we need to leave out the plural s anywhere
        S="s" NEWS="s"
        * BOTTLES ?? ^^1^^
        { S="" }
        * NEWBOTTLES ?? ^^1^^
        { NEWS="" }

        :0bfw  # Filter the body using sed
        | sed -e "s/$BOTTLES[ 	]*bottles*/$NEWBOTTLES bottle$NEWS/g" \
                -e "s/$MATCH[ 	]*bottles*/$BOTTLES bottle$S/g"

        # Okay, body filtering done. Now proceed as before:
        #  Resend the message with a new Subject: to myself

        | formail -I "Subject: $BOTTLES bottle$S$STRINGPART" | \

    # Still here? That means there are no more bottles.
    | formail -I "Subject: No bottles$STRINGPART" | \

# # You might want to uncomment this recipe to put the @&$0fF!! 
# # bottles of beer messages in their own mailbox
# :0:
# * ^Subject:\<*([1-9][0-9]|No)*\<+bottles?\<+of\<+beer\>*$
# ./beer

# To test this, INCLUDERC= this file from your regular .procmailrc
# (assuming you have one set up; check the manual pages if not)
# and send yourself a message with a subject line with the required
# number of bottles. A test message is in test.msg in this directory.
#  unix$ /usr/lib/sendmail $LOGNAME <test.msg
# or for testing purposes even just
#  unix$ procmail ./bodyfilter < test.msg
# or even
#  unix$ procmail VERBOSE=yes DEFAULT=./oops ./bodyfilter <test.msg

Download Source | Write Comment

Alternative Versions


>>  era said on 11/26/07 14:12:19

era I am the author of the code above. I used to have four different versions on my web site at the URL in the comments, but it was all lost in a backup disaster. (Actually I probably still have something in some murky old CVS repository somewhere, but I'm too disorganized to know for sure.)

Any chance you could update the Author: field?

PS. This form works very badly when cookies are disabled; any chance you could make it display a useful error message?

Download Source | Write Comment

Add Comment

Please provide a value for the fields Name, Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.

Please don't post large portions of code here! Use the form to submit new examples or updates instead!




Security Code: