Skip to content

Commit

Permalink
doc: add search and replace faq
Browse files Browse the repository at this point in the history
Closes #870
  • Loading branch information
z2oh authored and BurntSushi committed Apr 23, 2018
1 parent 6b15ce2 commit 8cb0394
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions FAQ.md
Expand Up @@ -20,6 +20,7 @@
* [How do I create an alias for ripgrep on Windows?](#rg-alias-windows)
* [How do I create a PowerShell profile?](#powershell-profile)
* [How do I pipe non-ASCII content to ripgrep on Windows?](#pipe-non-ascii-windows)
* [How can I search and replace with ripgrep?](#search-and-replace)
* [How is ripgrep licensed?](#license)
* [Can ripgrep replace grep?](#posix4ever)
* [What does the "rip" in ripgrep mean?](#intentcountsforsomething)
Expand Down Expand Up @@ -470,6 +471,70 @@ that the console will use for printing to UTF-8 with
will also reset when PowerShell is restarted, so you can add that line
to your profile as well if you want to make the setting permanent.

<h3 name="search-and-replace">
How can I search and replace with ripgrep?
</h3>

Using ripgrep alone, you can't. ripgrep is a search tool that will never
touch your files. However, the output of ripgrep can be piped to other tools
that do modify files on disk. See
[this issue](https://github.com/BurntSushi/ripgrep/issues/74) for more
information.

sed is one such tool that can modify files on disk. sed can take a filename
and a substitution command to search and replace in the specified file.
Files containing matching patterns can be provided to sed using

```
rg foo --files-with-matches
```

The output of this command is a list of filenames that contain a match for
the `foo` pattern.

This list can be piped into `xargs`, which will split the filenames from
standard input into arguments for the command following xargs. You can use this
combination to pipe a list of filenames into sed for replacement. For example:

```
rg foo --files-with-matches | xargs sed -i 's/foo/bar/g'
```

will replace all instances of 'foo' with 'bar' in the files in which
ripgrep finds the foo pattern. The `-i` flag to sed indicates that you are
editing files in place, and `s/foo/bar/g` says that you are performing a
**s**ubstitution of the pattren `foo` for `bar`, and that you are doing this
substitution **g**lobally (all occurrences of the pattern in each file).

Note: the above command assumes that you are using GNU sed. If you are using
BSD sed (the default on macOS and FreeBSD) then you must modify the above
command to be the following:

```
rg foo --files-with-matches | xargs sed -i '' 's/foo/bar/g'
```

The `-i` flag in BSD sed requires a file extension to be given to make backups
for all modified files. Specifying the empty string prevents file backups from
being made.

Finally, if any of your file paths contain whitespace in them, then you might
need to delimit your file paths with a NUL terminator. This requires telling
ripgrep to output NUL bytes between each path, and telling xargs to read paths
delimited by NUL bytes:

```
rg foo --files-with-matches -0 | xargs -0 sed -i 's/foo/bar/g'
```

To learn more about sed, see the sed manual
[here](https://www.gnu.org/software/sed/manual/sed.html).

Additionally, Facebook has a tool called
[fastmod](https://github.com/facebookincubator/fastmod)
that uses some of the same libraries as ripgrep and might provide a more
ergonomic search-and-replace experience.


<h3 name="license">
How is ripgrep licensed?
Expand Down

0 comments on commit 8cb0394

Please sign in to comment.