[comp.lang.icon] egrep & variable patterns

goer@SOPHIST.UCHICAGO.EDU (Richard Goerwitz) (07/06/90)

> Can anyone suggest a way to pass variable patterns  to egrep via a
> quoted argument as in,
> 
>    system("egrep 'ABC[d.]'")
> 
> I would like to be able to assemble the 'ABC[d.]' type parts on the
> fly and then push them out to the system.
> 
> Any ideas?

Sure.  I got a lot of ideas.  You judge for yourself which (if any) are
going to work out.

First of all, you could try something cute like:

  while ans := read(&input) do {
    system("/bin/egrep "||ans||" filename")
    }

I don't see what good this will do, because egrep will write to the
standard output and standard error output, and will not pipe to iconx.
You might as well write a shell script that does the same thing.

I might add that, unless you are writing a utility geared specifically
for the Unix environment, you'd best avoid such heavily OS-dependent
things as /bin/egrep (I gather the system function itself is not ter-
ribly portable, too).

Finally, you'll find that repeated calls to system() are expensive.  They
take a lot of time.

So much for my first suggestion.

A second suggestion might be to do something with

    open("/bin/egrep "||ans||" filename","pr")

You could then use egrep's output within Icon.

The problems here are again OS dependency and slowness.  Many implemen-
tations don't give you the "p" option with open().  And even if you can
do it, you'll pay the price of having to open and close pipes repeatedly.

A third suggestion might be to complain to the Icon Project that an in-
ternal grep-like command is needed, and try to convince them to create
one (after all, most C libraries have regex functions).

My objection to this is that it would be very un-Iconish.  Icon's pat-
tern-matching facilities are far more powerful than the facilities of-
fered by egrep, and of a wholly different kind.  You can easily construct
scanning expressions that will do anything egrep's regular expressions
will do.  I don't think anyone at the Icon project will be interested
in adding an igrep(), or whatever, function.

This leads to yet another solution to your problem:  Why not just use
Icon's intrinsic pattern-matching facilities?  Your

    egrep 'ABC[de]' filename

above can just as easily be expressed in Icon.  The following is very
inelegant, but suffices to show what can be done:

    every write(!open("filename") ? (tab(find("ABC")+3), any('de'), &subject))

You can, of course, use the results by assigning them to an intermediate
variable.  And you can vary the search pattern yourself simply by changing
the expression used after the question mark above.  You can vary the file
("filename" -> "filename1"|"filename2"|"filename3"), and anything else
you like.  Easy as pie, once you "get it."

The only problem likely to crop up in this connection has to do with con-
structing automata to match patterns at run-time.  You'll likely have some
trouble getting Icon to do this.

Lucky for you some nutcase posted a program called find_re, which is inten-
ded just for this very thing.  It works a bit like find() and a bit like
egrep, though it's not as fast as the C egrep program.  It's fast enough
for most purposes, though.  And since it's written in Icon, you don't have
to worry about piping, system(), and what not.  If you want find_re(),
please send a note to the following address:

    Richard L. Goerwitz               goer%sophist@uchicago.bitnet
    goer@sophist.uchicago.edu         rutgers!oddjob!gide!sophist!goer

This person appreciates it very much when people test his software, and
send back bug reports.