procmail
[Top] [All Lists]

Re: implemention right() function with procmail (efficiency)

1998-01-09 08:04:57
Jari Aalto asked,

|     Can anyone comment: these both give identical results, but what
|     is the preferred?

| VAR = "123"
| 
| SHELL = /bin/sh                         # --- CASE 1
| ret = `expr "$VAR" : '\(.*\)..'`

| saved = $SHELL                          # --- CASE 2
| SHELL = /bin/ksh
| ret   = `echo ${VAR%??} ;`  # semicolon to force invoking a shell
| SHELL = $saved

You don't need the semicolon; $SHELLMETAS includes the question mark, so
the first question mark will force a shell.

The first method runs sh (because of the asterisk) and expr; the second
method runs only ksh.  I'd guess that the overhead of assigning a variable
is negligible.

But here's my recommendation, which runs only expr:

 savemetas=$SHELLMETAS # if you haven't already done this one higher up
 SHELLMETAS
 ret = `expr "$VAR" : '\(.*\)..'`
 SHELLMETAS=$savemetas

My eternal admiration will go to anyone who figures out how to do this 
completely within procmail 3.11pre7, especially if the solution handles
variables that include newlines.

Actually, here's one, but it's really awful and needs a recursive INCLUDERC,
so it's worse than forking expr (and it doesn't handle embedded newlines
either):

   N=2 # fill in number of characters to drop from the right

   :0
   * 1^1 VAR ?? .
   * $ -$N^0
   {
    VARTOMEASURE = VAR  DOTSTRING = .  INCLUDERC = .builddotstringrc

# after all calls to .builddotstringrc are done and DOTSTRING is redefined

    :0
    * $ VAR ?? ^^\/$DOTSTRING
    { ret = $MATCH }
   }
   :0E
   { LOG="\$VAR is too short to drop $N characters.
"  }

# and here is .builddotstringrc

  :0
  * ! $ $VARTOMEASURE ?? ^^$DOTSTRING^^
  {
   DOTSTRING = .$DOTSTRING
   INCLUDERC = $_
  }

Yecch.

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