Marius Schulz
Marius Schulz
Front End Engineer

Fast Searching with ripgrep

In this post, I want to introduce you to ripgrep, a smart and fast command line search tool that I find myself using all the time when programming. ripgrep recursively searches directories for a regex pattern and outputs all matches that it finds.

#Why ripgrep?

So what makes ripgrep so great? After all, there are plenty of other search tools out there already, like grep, ack, or The Silver Searcher. For me, it boils down to the following reasons:

  • ripgrep is smart. It picks sensible defaults out of the box. I like that! For example, ripgrep respects .gitignore files and skips matching files and directories by default. It also ignores binary files, skips hidden files and directories, and doesn't follow symbolic links.
  • ripgrep is fast. In fact, it's very fast. I've thrown hundreds of thousands of files at it and didn't encounter any performance issues. Check out ripgrep is faster than {grep, ag, git grep, ucg, pt, sift} for a detailed analysis and various performance benchmarks.

ripgrep also has full Unicode support, can search compressed files, and optionally lets you switch its regex engine to use PCRE2 regular expressions.

#Installation

If you're using Homebrew, you can run the following command to install ripgrep:

$ brew install ripgrep

If you're using a different package manager, you can find a comprehensive list of installation instructions in the README.md on GitHub.

#The Basics

The name of the ripgrep executable is rg. In its most basic form, a simple search can look like this:

$ rg '// TODO'

This command will recursively search all files in the current directory (and its subdirectories) for the string // TODO and output the matches that it finds. If I run this command within the src directory of the prettier repository, the output looks like this:

$ rg '// TODO'
language-css/parser-postcss.js
521:  // TODO: Remove this hack when this issue is fixed:

language-markdown/parser-markdown.js
121:    // TODO: Delete this in 2.0

language-handlebars/parser-glimmer.js
32:      // TODO: `locStart` and `locEnd` should return a number offset

common/util-shared.js
42:  mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils

language-js/utils.js
239:// TODO: This is a bad hack and we need a better way to distinguish between

language-html/utils.js
80:  // TODO: handle non-text children in <pre>

common/internal-plugins.js
91:      // TODO: switch these to just `postcss` and use `language` instead.
134:      // TODO: Delete this in 2.0

language-html/constants.evaluate.js
21:  // TODO: send PR to upstream

language-js/printer-estree.js
5:// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.

The matches are grouped by file name. For each match, ripgrep prints the line number and highlights the matching substring.

#Frequently Used Options

For the remainder of this article, I'll go over several ripgrep options that I find myself using frequently to perform various search tasks when programming. I'm using the prettier repository to demonstrate the different options and what effect they have.

Feel free to clone the repository and follow along:

$ git clone https://github.com/prettier/prettier.git
$ cd prettier

Also, unless stated otherwise, I'm running all commands from within the src directory:

$ cd src

#No Options

Let's start with running ripgrep without any options. The default behavior might do exactly what you want already. Here, I am searching for the string // TODO within the current working directory:

$ rg '// TODO'
language-css/parser-postcss.js
521:  // TODO: Remove this hack when this issue is fixed:

language-markdown/parser-markdown.js
121:    // TODO: Delete this in 2.0

language-handlebars/parser-glimmer.js
32:      // TODO: `locStart` and `locEnd` should return a number offset

common/util-shared.js
42:  mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils

language-js/utils.js
239:// TODO: This is a bad hack and we need a better way to distinguish between

language-html/utils.js
80:  // TODO: handle non-text children in <pre>

common/internal-plugins.js
91:      // TODO: switch these to just `postcss` and use `language` instead.
134:      // TODO: Delete this in 2.0

language-html/constants.evaluate.js
21:  // TODO: send PR to upstream

language-js/printer-estree.js
5:// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.

We can see all matches, grouped by file name, with line numbers and highlighted matching substrings. If you want to quickly find a given string in a bunch of files and directories, this could be sufficient already.

#Files with Matches

Sometimes, you're not interested in seeing the matches themselves, but rather the paths of all files that contain at least one match. You can use the --files-with-matches option for that, or -l for short:

$ rg -l '// TODO'
language-markdown/parser-markdown.js
common/util-shared.js
language-html/constants.evaluate.js
language-css/parser-postcss.js
common/internal-plugins.js
language-js/printer-estree.js
language-html/utils.js
language-js/utils.js
language-handlebars/parser-glimmer.js

Note that ripgrep doesn't emit the files in a specific sort order by default. This is for performance reasons. If you want the list of file paths to be sorted alphabetically, you can use the --sort path option:

$ rg -l '// TODO' --sort path
common/internal-plugins.js
common/util-shared.js
language-css/parser-postcss.js
language-handlebars/parser-glimmer.js
language-html/constants.evaluate.js
language-html/utils.js
language-js/printer-estree.js
language-js/utils.js
language-markdown/parser-markdown.js

Please be aware that using the --sort path option disables all parallelism in ripgrep. Unless you're searching a large number of files though, you likely won't notice much of a performance difference.

The -l flag is particularly useful to pipe ripgrep's output into another program and perform additional operations on the matching files. For example, you could use ripgrep to find all files matching the string @format and format them with Prettier using the prettier executable:

$ rg -l '@format' | xargs prettier --write

#Files Without a Match

Sometimes, you might not be interested in files that do contain a match, but rather in those that don't. The --files-without-match option outputs exactly those files. Unlike the --files-with-matches option, the --files-without-match option does not have a short alias.

The following command lists all files that don't contain any of the strings var, let, or const. These JavaScript files don't contain any local variable declarations:

$ rg --files-without-match '\b(var|let|const)\b'
language-yaml/pragma.js
language-graphql/pragma.js
document/index.js
utils/get-last.js
language-js/preprocess.js
common/internal-plugins.js
common/third-party.js
utils/arrayify.js
language-html/pragma.js
common/errors.js
language-html/clean.js

And again, we can sort the list of files by using the --sort path option:

$ rg --files-without-match '\b(var|let|const)\b' --sort path
common/errors.js
common/internal-plugins.js
common/third-party.js
document/index.js
language-graphql/pragma.js
language-html/clean.js
language-html/pragma.js
language-js/preprocess.js
language-yaml/pragma.js
utils/arrayify.js
utils/get-last.js

Notice that we're using several regular expression features in our search pattern:

  • \b matches a word boundary. That way, the string delete won't match the let pattern.
  • | denotes an alternation. The pattern var|let|const matches any string that matches any of the patterns var, let, or const.

ripgrep will treat the search pattern as a regular expression by default; there's no need to specify another flag to turn the search pattern into a regular expression.

#Inverting Matches

Sometimes, you might be interested in all lines that do not match a given pattern, rather than those lines that do. ripgrep lets us show those lines using the --invert-match (or -v for short) flag.

Every now and then, I want to run a sanity check on all lines of code I've changed in a given Git commit. This is particularly helpful when running a codemod that changes hundreds or thousands of files. In those cases, I want to see a sorted and de-duplicated list of all changed lines. Here's the command I use:

git show | rg '^[-+]' | rg -v '^[-+]{3}' | sort | uniq

For the commit 6daa7e199e2d71cee66f5ebee3b2efe4648d7b99 in the Prettier repository, this is the output:

+      - "patch-release"
-      - patch-release

If I were to remove the rg -v '^[-+]{3}' bit from the pipe, the output would include file names as well, which is not what I want:

+      - "patch-release"
+++ b/.github/workflows/dev-test.yml
+++ b/.github/workflows/lint.yml
+++ b/.github/workflows/prod-test.yml
-      - patch-release
--- a/.github/workflows/dev-test.yml
--- a/.github/workflows/lint.yml
--- a/.github/workflows/prod-test.yml

By piping the output of the first search through rg -v '^[-+]{3}', I'm excluding all lines that start with three pluses or minuses, giving me a cleaner output at the end.

#Fixed Strings

Usually, it's useful that ripgrep treats every search pattern as a regular expression by default. We've seen in the previous section how we can search for several strings using the pattern var|let|const using an alternation, and there was no need for an additional flag to tell ripgrep to interpret the pattern as a regular expression rather than a fixed string.

However, if we want to search for a string that is not a well-formed regular expression, we get an error:

$ rg '?.'
regex parse error:
    ?.
    ^
error: repetition operator missing expression

In the above example, our search for the pattern ?. failed because the pattern is malformed. In a regular expression, the ? character denotes a repetition operator that makes the previous expression optional. It must follow an expression, which it doesn't do here.

We can tell ripgrep that we want it to interpret the search string as a fixed string rather than a regular expression pattern. All characters that would have special meaning in a regular expression (e.g. $, ?, |, …) will be matched verbatim. The flag we need to use to turn on this behavior is called --fixed-strings, or -F for short:

$ rg -F '?.'
language-js/printer-estree.js
4763:    return "?.";

Now, the search has succeeded and we get all results matching the string ?. verbatim.

#Context Around a Match

Sometimes, seeing only the matching lines themselves without any preceding or following lines might lack context. Take the search for // TODO as an example again:

$ rg '// TODO'
language-css/parser-postcss.js
521:  // TODO: Remove this hack when this issue is fixed:

common/util-shared.js
42:  mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils

common/internal-plugins.js
91:      // TODO: switch these to just `postcss` and use `language` instead.
134:      // TODO: Delete this in 2.0

language-markdown/parser-markdown.js
121:    // TODO: Delete this in 2.0

language-handlebars/parser-glimmer.js
32:      // TODO: `locStart` and `locEnd` should return a number offset

language-js/utils.js
239:// TODO: This is a bad hack and we need a better way to distinguish between

language-js/printer-estree.js
5:// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.

language-html/constants.evaluate.js
21:  // TODO: send PR to upstream

language-html/utils.js
80:  // TODO: handle non-text children in <pre>

Wouldn't it be helpful if we could see a few lines following each // TODO comment to get an idea of the code to which each comment refers? It turns out that ripgrep can do that. We can specify the --context option (or -C for short) and pass it an argument N to have ripgrep display N lines before and after each matching line:

$ rg '// TODO' -C 2
language-css/parser-postcss.js
519-  }
520-
521:  // TODO: Remove this hack when this issue is fixed:
522-  // https://github.com/shellscape/postcss-less/issues/88
523-  const LessParser = require("postcss-less/dist/less-parser");

language-markdown/parser-markdown.js
119-  parsers: {
120-    remark: markdownParser,
121:    // TODO: Delete this in 2.0
122-    markdown: markdownParser,
123-    mdx: mdxParser

common/util-shared.js
40-  isPreviousLineEmpty,
41-  getNextNonSpaceNonCommentCharacterIndex,
42:  mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils
43-  makeString: util.makeString,
44-  addLeadingComment: util.addLeadingComment,

common/internal-plugins.js
89-  {
90-    parsers: {
91:      // TODO: switch these to just `postcss` and use `language` instead.
92-      get css() {
93-        return eval("require")("../language-css/parser-postcss").parsers.css;
--
132-          .remark;
133-      },
134:      // TODO: Delete this in 2.0
135-      get markdown() {
136-        return eval("require")("../language-markdown/parser-markdown").parsers

language-js/utils.js
237-}
238-
239:// TODO: This is a bad hack and we need a better way to distinguish between
240-// arrow functions and otherwise
241-function isFunctionNotation(node, options) {

language-handlebars/parser-glimmer.js
30-      parse,
31-      astFormat: "glimmer",
32:      // TODO: `locStart` and `locEnd` should return a number offset
33-      // https://prettier.io/docs/en/plugins.html#parsers
34-      // but we need access to the original text to use

language-html/constants.evaluate.js
19-
20-const CSS_DISPLAY_TAGS = Object.assign({}, getCssStyleTags("display"), {
21:  // TODO: send PR to upstream
22-  button: "inline-block",
23-

language-html/utils.js
78-  }
79-
80:  // TODO: handle non-text children in <pre>
81-  if (
82-    isPreLikeNode(node) &&

language-js/printer-estree.js
3-const assert = require("assert");
4-
5:// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.
6-const comments = require("../main/comments");
7-const {

Now, we can see two lines before and after each // TODO comment, giving us some more context without having to open those files.

If you want to control the number of lines before and after the matching line independently, you can use the --before-context and --after-context options, respectively, or -B and -A for short. For example, here are all // TODO comments, followed by the next three lines:

$ rg '// TODO' -A 3
language-markdown/parser-markdown.js
121:    // TODO: Delete this in 2.0
122-    markdown: markdownParser,
123-    mdx: mdxParser
124-  }

common/util-shared.js
42:  mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils
43-  makeString: util.makeString,
44-  addLeadingComment: util.addLeadingComment,
45-  addDanglingComment: util.addDanglingComment,

common/internal-plugins.js
91:      // TODO: switch these to just `postcss` and use `language` instead.
92-      get css() {
93-        return eval("require")("../language-css/parser-postcss").parsers.css;
94-      },
--
134:      // TODO: Delete this in 2.0
135-      get markdown() {
136-        return eval("require")("../language-markdown/parser-markdown").parsers
137-          .remark;

language-handlebars/parser-glimmer.js
32:      // TODO: `locStart` and `locEnd` should return a number offset
33-      // https://prettier.io/docs/en/plugins.html#parsers
34-      // but we need access to the original text to use
35-      // `loc.start` and `loc.end` objects to calculate the offset

language-js/utils.js
239:// TODO: This is a bad hack and we need a better way to distinguish between
240-// arrow functions and otherwise
241-function isFunctionNotation(node, options) {
242-  return isGetterOrSetter(node) || sameLocStart(node, node.value, options);

language-js/printer-estree.js
5:// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.
6-const comments = require("../main/comments");
7-const {
8-  getParentExportDeclaration,

language-css/parser-postcss.js
521:  // TODO: Remove this hack when this issue is fixed:
522-  // https://github.com/shellscape/postcss-less/issues/88
523-  const LessParser = require("postcss-less/dist/less-parser");
524-  LessParser.prototype.atrule = function() {

language-html/constants.evaluate.js
21:  // TODO: send PR to upstream
22-  button: "inline-block",
23-
24-  // special cases for some css display=none elements

language-html/utils.js
80:  // TODO: handle non-text children in <pre>
81-  if (
82-    isPreLikeNode(node) &&
83-    node.children.some(

#Specific File Types Only

The --type option, or -t for short, lets you restrict searches to files of a specific type. To see how this option works, let's move up one level from the src directory into the root of the prettier repository:

$ cd ..

Let's confirm the current working directory:

$ pwd
/Users/marius/code/prettier

Alright, now we're ready. We can run a search for @format only on JavaScript files:

$ rg -t js '@format'
src/language-yaml/pragma.js
12:  return `# @format\n\n${text}`;

src/language-graphql/pragma.js
8:  return "# @format\n\n" + text;

src/language-css/clean.js
35:     * @format

src/language-html/pragma.js
8:  return "<!-- @format -->\n\n" + text.replace(/^\s*\n/, "");

src/main/core-options.js
110:    description: "Insert @format pragma into file's first docblock comment.",
234:      Require either '@prettier' or '@format' to be present in the file's first docblock comment

tests/insert-pragma/js/module-with-pragma.js
5: * @format

tests/require-pragma/js/module-with-pragma.js
3: * @format

Or we could search within Markdown files only:

$ rg -t md '@format'
docs/cli.md
101:Valid pragmas are `@prettier` and `@format`.
105:Insert a `@format` pragma to the top of formatted files when pragma is absent. Works well when used in tandem with `--require-pragma`.

docs/options.md
258: * @format
270:Prettier can insert a special @format marker at the top of files specifying that the file has been formatted with prettier. This works well when used in tandem with the `--require-pragma` option. If there is already a docblock at the top of the file then this option will add a newline to it with the @format marker.

website/blog/2017-09-15-1.7.0.md
108: * @format
187:- [**Add option to require @prettier or @format pragma**](https://github.com/prettier/prettier/pull/2772) by [@wbinnssmith](https://github.com/wbinnssmith)

website/blog/2017-05-03-1.3.0.md
25:- When pretty-printing a file, add `@format` to the first block comment like `@flow`.
26:- Have a lint rule with autofix that checks if the file is correctly pretty printed when `@format` is present.
29:- Update the default code templates to add `@format` to the header.
30:- When you run code formatting via cmd-shift-c inside of Nuclide, automatically insert the `@format` header.
31:- Disable all the stylistic rules like max-len when `@format` is in the header.
34:- When pushing a new release of prettier, also run it through all the files with `@format` in order to avoid getting warnings afterwards.
35:- Add tracking for the number of files with `@format` over time.

website/blog/2017-11-07-1.8.0.md
136:#### Add option to insert `@format` to first docblock if absent ([#2865](https://github.com/prettier/prettier/pull/2865)) by [@samouri](https://github.com/samouri)
138:In 1.7, we added an option called `--require-pragma` to require files contain an `/** @format */` pragma to be formatted. In order to add this pragma to a large set of files you can now use [`--insert-pragma`](https://prettier.io/docs/en/cli.html#insert-pragma) flag.

website/blog/2018-02-26-1.11.0.md
814: * @format
820: * @format

website/versioned_docs/version-stable/cli.md
102:Valid pragmas are `@prettier` and `@format`.
106:Insert a `@format` pragma to the top of formatted files when pragma is absent. Works well when used in tandem with `--require-pragma`.

website/versioned_docs/version-stable/options.md
259: * @format
271:Prettier can insert a special @format marker at the top of files specifying that the file has been formatted with prettier. This works well when used in tandem with the `--require-pragma` option. If there is already a docblock at the top of the file then this option will add a newline to it with the @format marker.

tests/markdown/real-world-case.md
292:Valid pragmas are `@prettier` and `@format`.
695: * @format

tests/require-pragma/markdown/with-pragma-in-multiline.md
6:  @format

Note that the type specifiers js and md are not file name extensions themselves. The type specifiers represent a set of file name extensions that are considered to be of that type:

  • js represents the extensions *.js, *.jsx, and *.vue
  • md represents the extensions *.markdown, *.md, *.mdown, and *.mkdn

You can pull up the complete list of supported type specifiers and the corresponding file name extensions by running the rg --type-list command.

#Using a Glob

Sometimes, using the --type (or -t for short) option might not give you enough control over which files to include in the search. In those cases, you can use the --glob (or -g for short) option. ripgrep will only search files whose paths match the specified glob.

For example, you could run a search for // TODO comments within only those JavaScript files whose name starts with "parser-":

$ rg -g 'parser-*.js' '// TODO'
language-markdown/parser-markdown.js
121:    // TODO: Delete this in 2.0

language-handlebars/parser-glimmer.js
32:      // TODO: `locStart` and `locEnd` should return a number offset

language-css/parser-postcss.js
521:  // TODO: Remove this hack when this issue is fixed:

#Showing the Help Page

Lastly, if you ever forget what a specific option is called, or if you want to see what other options are available, ripgrep provides two different levels of help:

  • rg -h: short descriptions with a condensed layout
  • rg --help: long descriptions with detailed explanations

Here's what ripgrep 12.0.0 prints when running the rg -h command:

ripgrep 12.0.0
Andrew Gallant <jamslam@gmail.com>

ripgrep (rg) recursively searches your current directory for a regex pattern.
By default, ripgrep will respect your .gitignore and automatically skip hidden
files/directories and binary files.

ripgrep's default regex engine uses finite automata and guarantees linear
time searching. Because of this, features like backreferences and arbitrary
look-around are not supported. However, if ripgrep is built with PCRE2, then
the --pcre2 flag can be used to enable backreferences and look-around.

ripgrep supports configuration files. Set RIPGREP_CONFIG_PATH to a
configuration file. The file can specify one shell argument per line. Lines
starting with '#' are ignored. For more details, see the man page or the
README.

ripgrep will automatically detect if stdin exists and search stdin for a regex
pattern, e.g. 'ls | rg foo'. In some environments, stdin may exist when it
shouldn't. To turn off stdin detection explicitly specify the directory to
search, e.g. 'rg foo ./'.

Tip: to disable all smart filtering and make ripgrep behave a bit more like
classical grep, use 'rg -uuu'.

Project home page: https://github.com/BurntSushi/ripgrep

Use -h for short descriptions and --help for more details.

USAGE:
    rg [OPTIONS] PATTERN [PATH ...]
    rg [OPTIONS] [-e PATTERN ...] [-f PATTERNFILE ...] [PATH ...]
    rg [OPTIONS] --files [PATH ...]
    rg [OPTIONS] --type-list
    command | rg [OPTIONS] PATTERN

ARGS:
    <PATTERN>    A regular expression used for searching.
    <PATH>...    A file or directory to search.

OPTIONS:
    -A, --after-context <NUM>               Show NUM lines after each match.
        --auto-hybrid-regex                 Dynamically use PCRE2 if necessary.
    -B, --before-context <NUM>              Show NUM lines before each match.
        --binary                            Search binary files.
        --block-buffered                    Force block buffering.
    -b, --byte-offset                       Print the 0-based byte offset for each matching line.
    -s, --case-sensitive                    Search case sensitively (default).
        --color <WHEN>                      Controls when to use color.
        --colors <COLOR_SPEC>...            Configure color settings and styles.
        --column                            Show column numbers.
    -C, --context <NUM>                     Show NUM lines before and after each match.
        --context-separator <SEPARATOR>     Set the context separator string.
    -c, --count                             Only show the count of matching lines for each file.
        --count-matches                     Only show the count of individual matches for each file.
        --crlf                              Support CRLF line terminators (useful on Windows).
        --debug                             Show debug messages.
        --dfa-size-limit <NUM+SUFFIX?>      The upper size limit of the regex DFA.
    -E, --encoding <ENCODING>               Specify the text encoding of files to search.
        --engine <ENGINE>                   Specify which regexp engine to use. [default: default]
    -f, --file <PATTERNFILE>...             Search for patterns from the given file.
        --files                             Print each file that would be searched.
    -l, --files-with-matches                Only print the paths with at least one match.
        --files-without-match               Only print the paths that contain zero matches.
    -F, --fixed-strings                     Treat the pattern as a literal string.
    -L, --follow                            Follow symbolic links.
    -g, --glob <GLOB>...                    Include or exclude files.
        --glob-case-insensitive             Process all glob patterns case insensitively.
    -h, --help                              Prints help information. Use --help for more details.
        --heading                           Print matches grouped by each file.
        --hidden                            Search hidden files and directories.
        --iglob <GLOB>...                   Include or exclude files case insensitively.
    -i, --ignore-case                       Case insensitive search.
        --ignore-file <PATH>...             Specify additional ignore files.
        --ignore-file-case-insensitive      Process ignore files case insensitively.
        --include-zero                      Include files with zero matches in summary
    -v, --invert-match                      Invert matching.
        --json                              Show search results in a JSON Lines format.
        --line-buffered                     Force line buffering.
    -n, --line-number                       Show line numbers.
    -x, --line-regexp                       Only show matches surrounded by line boundaries.
    -M, --max-columns <NUM>                 Don't print lines longer than this limit.
        --max-columns-preview               Print a preview for lines exceeding the limit.
    -m, --max-count <NUM>                   Limit the number of matches.
        --max-depth <NUM>                   Descend at most NUM directories.
        --max-filesize <NUM+SUFFIX?>        Ignore files larger than NUM in size.
        --mmap                              Search using memory maps when possible.
    -U, --multiline                         Enable matching across multiple lines.
        --multiline-dotall                  Make '.' match new lines when multiline is enabled.
        --no-config                         Never read configuration files.
    -I, --no-filename                       Never print the file path with the matched lines.
        --no-heading                        Don't group matches by each file.
        --no-ignore                         Don't respect ignore files.
        --no-ignore-dot                     Don't respect .ignore files.
        --no-ignore-exclude                 Don't respect local exclusion files.
        --no-ignore-files                   Don't respect --ignore-file arguments.
        --no-ignore-global                  Don't respect global ignore files.
        --no-ignore-messages                Suppress gitignore parse error messages.
        --no-ignore-parent                  Don't respect ignore files in parent directories.
        --no-ignore-vcs                     Don't respect VCS ignore files.
    -N, --no-line-number                    Suppress line numbers.
        --no-messages                       Suppress some error messages.
        --no-mmap                           Never use memory maps.
        --no-pcre2-unicode                  Disable Unicode mode for PCRE2 matching.
        --no-require-git                    Do not require a git repository to use gitignores.
        --no-unicode                        Disable Unicode mode.
    -0, --null                              Print a NUL byte after file paths.
        --null-data                         Use NUL as a line terminator instead of \n.
        --one-file-system                   Do not descend into directories on other file systems.
    -o, --only-matching                     Print only matches parts of a line.
        --passthru                          Print both matching and non-matching lines.
        --path-separator <SEPARATOR>        Set the path separator.
    -P, --pcre2                             Enable PCRE2 matching.
        --pcre2-version                     Print the version of PCRE2 that ripgrep uses.
        --pre <COMMAND>                     search outputs of COMMAND FILE for each FILE
        --pre-glob <GLOB>...                Include or exclude files from a preprocessing command.
    -p, --pretty                            Alias for --color always --heading --line-number.
    -q, --quiet                             Do not print anything to stdout.
        --regex-size-limit <NUM+SUFFIX?>    The upper size limit of the compiled regex.
    -e, --regexp <PATTERN>...               A pattern to search for.
    -r, --replace <REPLACEMENT_TEXT>        Replace matches with the given text.
    -z, --search-zip                        Search in compressed files.
    -S, --smart-case                        Smart case search.
        --sort <SORTBY>                     Sort results in ascending order. Implies --threads=1.
        --sortr <SORTBY>                    Sort results in descending order. Implies --threads=1.
        --stats                             Print statistics about this ripgrep search.
    -a, --text                              Search binary files as if they were text.
    -j, --threads <NUM>                     The approximate number of threads to use.
        --trim                              Trim prefixed whitespace from matches.
    -t, --type <TYPE>...                    Only search files matching TYPE.
        --type-add <TYPE_SPEC>...           Add a new glob for a file type.
        --type-clear <TYPE>...              Clear globs for a file type.
        --type-list                         Show all supported file types.
    -T, --type-not <TYPE>...                Do not search files matching TYPE.
    -u, --unrestricted                      Reduce the level of "smart" searching.
    -V, --version                           Prints version information
        --vimgrep                           Show results in vim compatible format.
    -H, --with-filename                     Print the file path with the matched lines.
    -w, --word-regexp                       Only show matches surrounded by word boundaries.