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.