Neil Syiemlieh
Posted on October 27, 2023
The Problem
I have a command reference. It's a text file with lots of CLI commands I've written down because I don't want to memorise them all. For example here's a bunch of network-related commands:
nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
netstat --tcp
netstat --program
netstat --listening
When I want to look up a command, I don't always remember the actual command I want. Let's suppose I need to do a DNS lookup. I might not remember that I need dig
or nslookup
. Or I might just need something to do with networking. How can I search for all DNS commands or networking commands?
Halfway There: A Better Command Reference
I can add headings and sub-headings to the list above. Each heading starts with a hashtag to differentiate it from the actual commands.
# Networking
# DNS
nslookup -type=ns example.com
nslookup -type=txt example.com
nslookup -type=cname example.com
nslookup example.com 1.1.1.1
dig example.com txt
dig example.com cname
# See processes and ports used
netstat --tcp
netstat --program
netstat --listening
This is better, but I'd still need to search for DNS and scan over the following lines to find the command I want. A better way is to associate a bunch of tags with each line. Each tag would place the line in some category. A DNS category, a networking category. But manually writing "#dns" after every DNS command in my list would be tedious. It would also pollute the command reference with tags everywhere.
The Solution: ltag + fzf
So instead I created a tool read the above text, append the heading to every line as a tag, and print out the result. That would convert the above text to the following:
nslookup -type=ns example.com #networking #dns
nslookup -type=txt example.com #networking #dns
nslookup -type=cname example.com #networking #dns
nslookup example.com 1.1.1.1 #networking #dns
dig example.com txt #networking #dns
dig example.com cname #networking #dns
netstat --tcp #networking #see-processes-and-ports-used
netstat --program #networking #see-processes-and-ports-used
netstat --listening #networking #see-processes-and-ports-used
I call this tool "ltag", short for "Line tag". It's written in Go. Here's the git repository: mebble/ltag.
With tagging out of the way, I now have the ability to search.
The CLI search tool I use is fzf. fzf takes in any text stream and spins up a TUI for you to fuzzy search through the text. I can pipe my tool's output to fzf and violà, I can now search by command and by tag!
I still have one problem though. The purpose of looking up commands is so that I can run them. When I select a command through fzf, the tags associated with that command also get selected. I'd like to get rid of these tags once I've found the command I want. So my tool is also able to remove tags from the selected line.
I can now do a quick command lookup using a shell alias:
alias cl="cat ~/.cmd-reference.txt | ltag | fzf | ltag --trim | pbcopy"
Beyond a Command Reference
This tool could help you search through any list of things. And the list doesn't have to be in a text file. ltag reads from standard input, so you can pipe the output of any command to it.
This is my first Go project, and I'm glad I found a way to create something actually useful. So here it is, hope you find it useful as well.
Posted on October 27, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.