Skip to content

erik/fnr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fnr – find and replace

Like find ... | xargs sed ..., but with a memorable interface.

Recursively find and replace patterns in files and directories.

fnr [OPTIONS] FIND REPLACE [PATH...]

About

fnr is intended to be more intuitive to use than sed, but is not a drop in replacement. Instead, it's focused on making bulk changes in a directory, and is more comparable with your IDE or editor's find and replace tool.

fnr is alpha quality. Don't use --write in situations you wouldn't be able to revert.

Examples

Replace "old_function" with "new_function" in current directory.

fnr old_function new_function

Choose files and directories to consider.

fnr 'EDITOR=vim' 'EDITOR=emacs' ~/.zshrc ~/.config/

We can use --literal so the pattern isn't treated as a regular expression.

fnr --literal 'i += 1' 'i++'

Replace using capturing groups.

fnr 'const (\w+) = \d+;' 'const $1 = 42;'

Use -W --write to write changes back to files without prompting.

fnr --write 'Linus Torvalds' 'Linux Torvalds'

Use -I --include to only modify files or directories matching a pattern.

fnr --include 'Test.*\.kt' 'mockito' 'mockk'

Similarly, use -E --exclude to ignore certain files.

fnr --exclude ChangeLog 2021 2022

Files and directories to consider can also be given over standard input.

find /tmp/ -name "*.csv" -print | fnr "," "\t"

Installation

cargo install fnr

If you'd prefer to build from source instead:

$ git clone git@github.com/erik/fnr.git
$ cd fnr
$ cargo install --path .

Performance

Built on top of ripgrep's path traversal and pattern matching, so even though performance isn't an explicit goal, it's not going to be the bottleneck.

In fact, without writing changes back to files, it's imperceptibly slower than ripgrep itself.

Command Mean [ms] Min [ms] Max [ms] Relative
rg "EINVAL" ./linux 510.4 ± 25.8 467.6 555.0 1.00
fnr "EINVAL" "ERR_INVALID" ./linux 620.4 ± 22.1 573.7 649.7 1.22 ± 0.08
fnr --write "EINVAL" "ERR_INVALID" ./linux 3629.0 ± 76.2 3538.0 3802.3 7.11 ± 0.39
ag "EINVAL" ./linux 2560.0 ± 43.6 2518.4 2668.1 5.02 ± 0.27
grep -irI "EINVAL" ./linux 37215.8 ± 7444.7 31316.1 49096.6 72.92 ± 15.04

Similar Tools

If fnr doesn't quite fit what you're looking for, also consider:

Releases

No releases published

Packages

No packages published

Languages