procmail
[Top] [All Lists]

Re: 'OR'ed conditions

1997-03-26 12:44:13
Roy Rapoport asked:

| > Is there a way to specify 'OR'ing of these conditions, or do I
| > need to do a separate recipe for each of them?

And Guy Geens suggested,

| Use scoring:
| :0:
| * 9876543210^0 condition1
| * 9876543210^0 condition2
| * condition3
| folder
| 
| condition3 must be fulfilled, as well as one of condition1 or condition2.
| 
| See man 5 procmailsc for details. procmail treats the number
| 9876543210 as `infinitely large'. Therefore, it will skip all
| following scoring recipes.

Yes, note: after the score reaches the supremum (which is actually
2147483647, but 9876543210 is much easier to remember) all succeeding
*weighted* recipes will be skipped.  Guy purposely illustrated how an
unweighted recipe will still be evaluated and must pass.

[Contrarily, if the score reaches infemum, which is -2147483647, the
 recipe is considered unmatched and all remaining conditions, weighted
 or not, will be skipped.]

If you wanted to OR all three, you could do this:

  :0:
  * 9876543210^0 condition1
  * 9876543210^0 condition2
  * 1^0 condition3
  folder

For the last condition to be ORed, any positive weight will do.  Of course,
it is most efficient to put the most common condition first.

There are two other approaches to Roy's question, however.

First -- ok, we'll say that supremum scores are the first; I wouldn't have
listed it first but I've already quoted it from Guy.  So there are two more.

Second, where you can, use alternation as Lars Kellogg-Stedman illustrated
for regexp conditions:

 * regexp1|regexp2

or if they share parts, something like reg(exp1|exp2).

If you are ORing exitcode conditions and the one that occurs more frequently
already requires a shell, and you're using sh or a shell with sh-style
syntax, you can OR two exitcode conditions the way you would in a shell
script:

 * ? command1 || command2

Third, when you cannot combine conditions into one (one is negated and one is
not, or they have different search areas, or one is an exitcode and the other
is a regexp, or either is a size test), you can always apply DeMorgan's law:
AND the inverses and then invert the result:

  :0 # add flags that affect conditions
  * ! condition1
  * ! condition2
  * ! condition3
  { } # this is a legal no-op
  :0E # add flags that affect the action and local lockfile if needed
  action

If any of the conditions were already negated, drop the exclamation point:
for example, to act if condition4 or condition6 is met or if condition5
is NOT met,

 :0
 * ! condition4
 * condition5
 * ! condition6
 { }
 :0E
 action

<Prev in Thread] Current Thread [Next in Thread>