The nouveau command line text trifecta: ripgrep, sd, fd
Here are three programs I always install.
- fd - an alternative to
find
- rg (ripgrep) - an alternative to
grep
- sd - replaces some uses of
sed
ripgrep
A very fast way to search through text files for a string pattern.
It has tons of options, but I use a few flags all the time.
-F
treats the pattern as a literal string, not a regular expression. This is what I want 85% of the time.-C
accepts a number as an argument, and shows you the context around the pattern when there's a match. Passing-C 1
will show 1 line before and 1 line after the match. Compare with-A
and-B
.-g
accepts a glob pattern and controls the files that ripgrep will consider. You can specify this multiple times.
For example, the following will print all instances of func init()
in files with a ".go" extension.
rg -F 'func init()' -g '*.go'
Take note of the single quotes for the glob argument. You'll probably need those.
The -g
flag can also be prefixed with ! to ignore files that
match a pattern. Our previous example can be modified to ignore test
files.
rg -F 'func init()' -g '!*_test.go` -g '*.go'
fd
This one has a different job. Ripgrep searches for patterns inside text files, but fd searches for files based on patterns in filenames.
By default it prints the filepath of every file recursively, one file per line. This gives you a way to count the number of files in a directory.
fd | wc -l
Hidden files are ignored by default, as are patterns listed in
.gitignore files. Include them with -H
and -I
, respectively.
fd -H -I | wc -l
Another flag I often use is -e
. This limits the search by
file extension and can be specified multiple times. Here we
search recursively for all txt and html files.
fd -e html -e txt
fd is sometimes available as fd-find or fdfind in package managers.
sd
The sd command does find + replace. It modifies the files in-place by default. This is potentially dangerous, so only do that if you're using version control.
I always use the -F
flag to search for a literal string and replace
it with another literal string. This example replaces every instance
of "yes" with "no" in three text files.
sd -F 'yes' 'no' one.txt two.txt three.txt
If you need to file and replace over a lot of files, you can use fd to generate the list of filepaths.
The previous example, but for every txt file in our project.
sd -F 'yes' 'no' $(fd -e txt)
sd supports regular expressions, too.