Subject: Repalcement for grep(1)
To: None <freebsd-hackers@FreeBSD.ORG,,>
From: Jamie Howard <>
List: tech-userlevel
Date: 07/03/1999 15:18:07

I have used FreeBSD for a couple years now.  It is the only OS on my
desktop.  I have learnt many things from its source.  I felt it was time
to give something back.  A few minutes later I decided to offer it to all
BSDs.  I also will offer it to the DaemonLinux group, Apple, the  Darwin
group, and Tenon Systems, after public acceptence.  If there is anyone
else out there using a BSD base and GNU grep, they can have it too.

Looking aroud, I thought it would be great to try to replace one of the
GNU utilites included in the base with a version which is freely
redistributable.  I figured a compiler was beyond me, but a a couple of
the simpler utilities caught my eye.  Grep was first.

All of the code is original except for binary.c.  It is used with the -a
option to prevent searching binary files.  binary.c is extricated from
less-332's binary checking code.  I was just that lazy.

I made the version in FreeBSD 4.0 my target except for -A num, -B num, -C,
-num, and -Z.  These are not required by the Single Unix Specification or
POSIX and I felt they would bloat my code too significantly.  

I added the -o option from 4.4BSD-Lite2's implementation of egrep.  I also
stole it's man page.

One of the primary concerns was simplicity.  Looking through the code, you
should nobody should have any difficuly understanding the code.  Regex
does all the heavy work.  The object code is about 16% of the size of GNU 
grep.  I also do not use mmap(), I treat the file as a simple stream
instead.  My code is also a bit slower on larger files, but a bit faster
on smaller files.  Sometimes I am an order of magnitude slower.  I am
never that much faster.  I think not using mmap is the reason, but I do
not know for certain.

Now, I am having a problem though.  I cannot figure out how to implement
-w and -x.  For -x, I tried modifying the regular expression (foo) into
^(foo)$ before compiling, but that did not work.  I intended to do
something similar with -w.  Anyway, I am probably missing the obvious, but
does anyone have any ideas regarding how I should implement -w and -x?

If anyone can help with the -w and -x problems, would like to test, or has
any other comments, let me know.  I'd also like advice on the speed
issue.  Also, since I am at it, if you want anything added, lay it on me,
either code or ideas.  :)

The source code can be found at

The source was written and tested on a FreeBSD 3.2 system.  I have also
compiled under BSDi 3.1.  It should work on any BSD and most any Unix.
The Makefile is written in the style of the rest of the FreeBSD utilites
so that it can be dropped right into /usr/src/usr.bin someday.  Only minor
modifications should be needed for BSDi, NetBSD, and OpenBSD.  I have not
built this on either NetBSD or OpenBSD but expect no problems.  If anyone
does have problems please let me know.  Fixes are even better. 

Thank you everyone, Jamie

To Unsubscribe: send mail to
with "unsubscribe freebsd-hackers" in the body of the message