I have written several posts on regex, and its combination with grep is one of the more practical combinations on the command line. But on reading Ian Miell’s post about grep, I was reminded why I don’t use it so much — it is a thicket of flags, somewhat typical of what Linux forces users to chop through. Ian counted about 50 flags, and it is therefore common for developers to remember just one pattern and forlornly hope they can apply it everywhere.
However, Ian shows a simple organising principle that can help with building grep searches up. The grep flags can roughly be divided by what to read, what to match, what to report, and in what context. This may not be a machete, but it should prevent panic. In this post, I’ll show an example of building a search, before using the Warp console to help further reduce the effort in future usage.
As an example, I have a bunch of JSON document data in my game project, and I want to look at readable references. While my IDE is the best way to sort through code, it is still efficient to have a way to get a quick command line response to a query. And sometimes we are not in a position to assume that other tools are at hand.
In this example, I want to search through JSON data for medical references in the game — these could be items, locations, events and characters — to remind myself of how healing is dealt with. A quick report will remind me of which ideas have been implemented, and where.
What To Read
I only want to look within JSON files, recursing into subdirectories from the root of the project.
grep -r --include=*.json 'pattern' ./
This is what we need to read, so let’s move on to the next section.
What To Match
OK, this is a case of matching our knowledge of regex to the form grep is happy with. That means using -E, which has replaced egrep
or extended grep:
grep -E '(f|F)irst (A|a)id|(M|m)edical|(D|d)octor'
It’s important that we use the pattern to control capitalization, as there are lots of mixed cases in the text. But we don’t necessarily want to search case insensitively — that might dredge up things like camel casing in keys. We just want the textual information to remind us of what the content looks like.
Note that if we didn’t use the -E flag, we could get the above to work by escaping the special regex characters.
How To Report
The output context I want is the line above and below with the filename and line number.
Here we can use Ian’s ABC approach — After, Before and Context — for both. We want the report to show one line above and one line below. But we also need the line number. (Ideally, we wouldn’t repeat the filename, but that requires too much work.)
grep -n -C1
OK, let’s put this altogether:
grep -ErnC1 --include=*.json '(f|F)irst (A|a)id|(M|m)edical|(D|d)octor’
Using the search in the Warp console on my MacBook, I get back what I hoped for:
Note that we could also use word boundaries (b
) to help suppress the selection of ID or key values in compound words that we saw in the first file results returned:
'b(f|F)irst (A|a)idb|b(M|m)edicalb|b(D|d)octorb'
While a less pleasing pattern, it does the job:
Parameterized With Warp
An extra trick is to turn this search into a parametrized command in Warp, so we can quickly search for other patterns too. This process is called a Workflow (a poorly chosen name!). This is especially handy if we want to share a grep command with a team.
Now if I go back to my command, I can Save as Workflow from the right side triple dot menu in the block:
Warp isolates the command so that I can work on it:
I replace the search term with {{}} and claim the argument:
Before creating, you can hit “>_” to check that you have this got this recorded correctly:
Then hit “Create.” It should be saved to “Personal”, if you aren’t in a Warp Drive working with a team.
So to recall the workflow, Command Search (Ctrl-R) and start typing workflows, then tab:
Just tap and the command appears ready to be edited:
We could also just save this as an alias within our shell setup, if we want to keep strictly to personal Unix use.
Conclusion
While grep and regex are natural bedfellows, regex is a useful tool on the command line and within IDEs, whereas grep is solely a unix command. After mastering regex, tools like grep become much more useful. Even if we can’t remember the flags, by remembering “where, what and how,” we can quickly find the flags we know we need.
The post Introduction to Using Grep With Regular Expressions via Warp appeared first on The New Stack.