Episode: 4597
Title: UNIX Curio #2 - fgrep
Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr4597/hpr4597.mp3
Transcribed: 2026-07-31 16:14:46 (official HPR transcript)

---

This is Hacker Public Radio Episode 4597, for 2026-03-17
Today's show is entitled, "UNIX Curio #2 - fgrep"
The host is Vance and the duration is 00:11:50
The flag is Clean, and the license is CC-BY-SA
The summary is "Searching without regular expressions"
Hi there, I'm Vance and welcome to Unix Curio number 2.
This series is dedicated to exploring little known and occasionally useful, trinkets lurking
in the dusty corners of Unix Lake operating systems.
Imagine, if you will, a Jane Austen novel about three sisters.
The first is well known and celebrated by everyone.
The second, while slightly smarter and more capable, is significantly less popular.
And the third languages in near-total isolation and obscurity.
These three sisters live on any Unix Lake system, and their names are Grepp, E-Grepp, and
F-Grepp.
I will assume that you are already familiar with Grepp.
Grepp works pretty much the same, except that she handles extended regular expression syntax.
The E is for extended.
When you're writing shell scripts intended to be portable, be careful to call E-Grepp if
your expression uses the plus symbol, question mark, vertical pipe symbol, or curly
braces as metacaractors.
Some versions of G-Neu-Grepp make no distinction between basic and extended regular expressions,
so you might be surprised when your script works on one system, but not another.
If you go to the POSIX-Grepp specification, linked from the show notes, you will find
a link to the specification page describing basic and extended regular expressions.
This might help you understand the difference between them and where you would need to use
Grepp or E-Grepp.
But our Unix Curio for today is poor unnoticed F-Grepp.
While the plainest sister of the three, she really doesn't deserve to be ignored, sometimes
she's exactly what you need.
The F in her name stands for either fixed string or fast, depending on who you ask.
She does not handle regular expressions at all.
The pattern she has given is taken literally.
This can be a great advantage when what you are searching for contains characters having
special meaning in a regular expression.
As an example, suppose that you have a directory full of code files and want to find
which files reference a particular array element.
If the language that these files are written in uses square brackets for array elements,
this won't be straightforward.
Regular expressions in Grepp treat a set of characters inside square brackets as representing
any one of the characters listed in that set.
Actually, it's a little bit more complicated than that.
You can look up bracket expressions in a reference about regular expressions if you want
the gory details.
To find text containing a literal set of square brackets with Grepp, you would need to escape
each square bracket with a backslash character.
You can see the show notes for an example of what I mean.
If what you're searching for contains other characters that are special to Grepp, you
would similarly need to put backslashes before these to force Grepp to search for the literal
characters instead.
This can get tedious if your search string has many non-alphanumeric characters and
you don't remember off the top of your head, which ones have special significance in
regular expressions.
Before anyone jumps into correct me, I should point out that there are other possible
ways to escape medicaractors in a regular expression.
A backslash is just the simplest approach, so that's what I'm describing.
Thankfully, there is an easier way to deal with these special characters.
Just use F-Grepp instead.
F-Grepp treats each character as simply representing itself.
You can therefore search for patterns including dot characters, square brackets, and
asterisks with abandon.
They will only match themselves.
Of course, you lose the flexibility of regular expressions, so F-Grepp isn't the right
tool for all occasions, but when you need it, it's there.
Where I most often find F-Grepp to be particularly handy is when searching through log files
for IP version for addresses.
With ordinary Grepp, a pattern containing an IPv4 address with dots would probably match
a bunch of addresses you're not interested in, because the dot medicaractor will match
any single character.
To make sure you only matched a literal dot, you would have to escape each one, or better
yet use F-Grepp.
While I was researching this episode, I discovered a capability all three of these
sisters have that previously I didn't fully appreciate.
You might be familiar with using the vertical pipe symbol with E-Grepp to match either
what is to the left of the symbol or to the right.
The similar thing can be accomplished by using a pattern list instead of a single pattern.
Anywhere that you would give a pattern to Grepp, E-Grepp, or F-Grepp, such as on the command
line or from a file, you can instead supply a list separated by new lines.
The utility will then match lines that match any of the patterns in the list.
So in my IP address example, I could feed a list of addresses to F-Grepp instead of just
one and get back all of the lines from the log file that matched any of the addresses
in the list.
You should note that to provide a pattern list on the command line, you will need to
enclose it in single or double quotation marks to prevent the shell from trying to execute
the command when you type a new line.
But what about the claim that F-Grepp is fast?
On many systems, including those with canoe utilities, there is just one single binary
that changes its behavior depending on whether it is called as Grepp, E-Grepp, or F-Grepp.
This is actually in line with the POSIX standard, which seeks to move away from E-Grepp
and F-Grepp in favor of a single Grepp command.
This Grepp command takes the Hiphon uppercase E option for using extended regular expressions
and the Hiphon uppercase F option for doing fixed string searches.
Back in 2010, when I first wrote this article, I tested Grepp against F-Grepp for speed.
I found that when specifying a single pattern on the command line with the GNU version,
F-Grepp wasn't really any faster than Grepp.
The main overhead that is saved with F-Grepp is the effort necessary to compile the regular
expression before the searching starts.
However, when I tried using the Hiphon lowercase F option to specify a file containing
a list of a couple dozen patterns, F-Grepp could consistently produce a 20% time savings.
One systems where Grepp and F-Grepp are different binaries, there can potentially be a
more dramatic difference in speed and even memory usage.
I hope you'll excuse me for going a little bit off topic, but I wanted to briefly touch
on pro-compatible regular expressions.
I already talked about the basic and extended regular expressions, and the differences that
are between them, pro-compatible regular expressions add some extra capabilities beyond
what extended regular expressions are able to do.
These are supported by several programming languages, not just Pearl, and the GNU version
of Grepp can also be told to use them.
However, they are not part of the POSIC standard, and other Grepp implementations typically
do not understand them.
So it is good idea to avoid them when writing a shell script intended to be portable.
When you're writing a script in Pearl, Python, or another language that supports them, before
using these pro-compatible regular expressions, it's advisable to investigate which versions
of the language support them, and whether support is built in or provided by an additional
library.
Then you can advise potential users what they need to have to run your script, or you
might instead decide to use a type of regular expression that has wider support.
Getting back to our hypothetical Austin novel, the neglected sister would probably be driven
to a bad end, to be only spoken of afterward in hushed whispers.
Don't let that happen.
Whenever you need to search for a string, but don't require the power of regular expressions,
get into the habit of calling on F-Grepp.
She can be very helpful and deserves more intention than she gets.
You'll save yourself the trouble of worrying about medic characters, and maybe some running
time as well.
Thanks for listening, and keep an eye out for our next Unix Curio, which will be about
the base name utility here on Hacker Public Radio.
If you have a question, or a suggestion for a future topic, please comment on this episode
on the HPR website.
You have been listening to the Hacker Public Radio podcast, at hackerpublicradio.org.
Today's show was contributed by a HPR listener like yourself.
If you ever thought of recording a podcast, then visit the HPR site to find out how easy it really is.
Hosting for HPR has been kindly provided by anhonesthost.com, the Internet Archive, rsync.net, and the HPR Community Content Delivery Network.
Unless otherwise stated, today's show is released under a Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.
