This is a work-in-progress draft version.
Options overview
This chapter will cover some of the options provided by ripgrep
with examples.
Literal search
Use -F
option to search for fixed strings. The tool will also try to automatically apply literal search optimizations based on the search string provided.
$ cat programming_quotes.txt
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it by Brian W. Kernighan
Some people, when confronted with a problem, think - I know, I will
use regular expressions. Now they have two problems by Jamie Zawinski
A language that does not affect the way you think about programming,
is not worth knowing by Alan Perlis
There are 2 hard problems in computer science: cache invalidation,
naming things, and off-by-1 errors by Leon Bambrick
$ rg -F 'twice' programming_quotes.txt
1:Debugging is twice as hard as writing the code in the first place.
$ echo 'int a[5]' | rg -F 'a[5]'
int a[5]
Case insensitive search
$ rg -i 'jam' programming_quotes.txt
6:use regular expressions. Now they have two problems by Jamie Zawinski
$ printf 'Cat\ncOnCaT\nscatter\ncut' | rg -i 'cat'
Cat
cOnCaT
scatter
Invert matching lines
$ seq 5 | rg -v '3'
1
2
4
5
$ printf 'goal\nrate\neat\npit' | rg -v 'at'
goal
pit
Line number and count
Default settings like line number and color depend upon context. If output is terminal, these are on, but if output is redirected to file, another command, etc then they are turned off. Also, if stdin
is the only source of input, line number option won't turn on.
$ # -n will ensure line numbers are available for further processing
$ rg -n 'twice' programming_quotes.txt
1:Debugging is twice as hard as writing the code in the first place.
$ # -N to turn off default line number prefix on terminal
$ rg -N 'twice' programming_quotes.txt
Debugging is twice as hard as writing the code in the first place.
$ # count of matching/non-matching lines
$ rg -c 'in' programming_quotes.txt
8
$ printf 'goal\nrate\neat\npit' | rg -vc 'g'
3
$ # multiple file input
$ seq 15 | rg -c '1' programming_quotes.txt -
<stdin>:7
programming_quotes.txt:1
$ cat <(seq 15) programming_quotes.txt | rg -c '1'
8
If any input file doesn't have a match, -c
will not display that file in output. You can use --include-zero
to display files without matches as well.
$ rg -c '1' *
search_strings.txt:1
programming_quotes.txt:1
$ # same as: grep -c '1' *
$ rg -c --include-zero '1' *
search_strings.txt:1
programming_quotes.txt:1
colors_1:0
colors_2:0
Limiting output lines
$ # limit no. of matching lines displayed for each input file
$ rg -m3 'in' programming_quotes.txt
1:Debugging is twice as hard as writing the code in the first place.
3:by definition, not smart enough to debug it by Brian W. Kernighan
5:Some people, when confronted with a problem, think - I know, I will
$ seq 1000 | rg -m4 '2'
2
12
20
21
Multiple search strings
$ # search for '1' or 'two', similar to conditional OR boolean logic
$ rg -e '1' -e 'two' programming_quotes.txt
6:use regular expressions. Now they have two problems by Jamie Zawinski
12:naming things, and off-by-1 errors by Leon Bambrick
$ # specify a file as source of search strings
$ printf 'two\n1\n' > search_strings.txt
$ rg -f search_strings.txt programming_quotes.txt
6:use regular expressions. Now they have two problems by Jamie Zawinski
12:naming things, and off-by-1 errors by Leon Bambrick
$ # -f and -e can be combined and used multiple times
$ rg -f search_strings.txt -e 'twice' programming_quotes.txt
1:Debugging is twice as hard as writing the code in the first place.
6:use regular expressions. Now they have two problems by Jamie Zawinski
12:naming things, and off-by-1 errors by Leon Bambrick
$ # match lines containing both 'in' and 'not' in any order
$ # similar to conditional AND boolean logic
$ rg 'in' programming_quotes.txt | rg 'not'
by definition, not smart enough to debug it by Brian W. Kernighan
A language that does not affect the way you think about programming,
is not worth knowing by Alan Perlis
Get filename instead of matching lines
$ # list filename if it contains 'are' anywhere in the file
$ rg -l 'are' programming_quotes.txt search_strings.txt
programming_quotes.txt
$ rg -l 'xyz' programming_quotes.txt search_strings.txt
$ rg -l '1' programming_quotes.txt search_strings.txt
search_strings.txt
programming_quotes.txt
$ # list filename if it does NOT contain 'xyz' anywhere in the file
$ rg --files-without-match 'xyz' programming_quotes.txt search_strings.txt
search_strings.txt
programming_quotes.txt
$ rg --files-without-match 'are' programming_quotes.txt search_strings.txt
search_strings.txt
Filename prefix for matching lines
$ # by default, filename isn't printed for single input
$ rg '1' programming_quotes.txt
12:naming things, and off-by-1 errors by Leon Bambrick
$ # use -I to suppress filename prefix for multiple input
$ seq 1000 | rg -I -m3 '1' - programming_quotes.txt
1:1
10:10
11:11
12:naming things, and off-by-1 errors by Leon Bambrick
$ # default behavior for multiple file input
$ seq 1000 | rg -m3 '1' - programming_quotes.txt
programming_quotes.txt
12:naming things, and off-by-1 errors by Leon Bambrick
<stdin>
1:1
10:10
11:11
$ # use -H to always show filename prefix
$ rg -H '1' programming_quotes.txt
programming_quotes.txt
12:naming things, and off-by-1 errors by Leon Bambrick
To get output format same as GNU grep
$ # use --no-heading to get same style as GNU grep
$ rg --no-heading -H '1' programming_quotes.txt
programming_quotes.txt:12:naming things, and off-by-1 errors by Leon Bambrick
$ # --no-heading is automatically assumed when output is redirected
$ rg -Hn '1' *.txt | cat -
search_strings.txt:2:1
programming_quotes.txt:12:naming things, and off-by-1 errors by Leon Bambrick
The vim
editor has an option -q
that allows to easily edit the matching lines from rg
output if it has both line number and filename prefixes. Use --vimgrep
option instead of -Hn
to allow vim
to place cursor from start of match instead of start of line.
$ rg --vimgrep '1' *.txt
search_strings.txt:2:1:1
programming_quotes.txt:12:27:naming things, and off-by-1 errors by Leon Bambrick
$ # use :cn and :cp to navigate to next/previous occurrences
$ # the status line at bottom will have additional info
$ vim -q <(rg --vimgrep '1' *.txt)
Colored output
By default, --color=auto
setting is used to distinguish matching portions, line numbers, filenames, etc. Use never
to disable color and always
to carry forward color information for further processing.
Below image shows difference between auto
and always
. In the first case, in
is highlighted even after piping, while in the second case, in
is not highlighted. In practice, always
is rarely used (for example: piping results to less -R
) as it has extra information added to matching lines and could cause undesirable results when processing such lines. You can also use -p
option, which is a shortcut to enable --color=always --heading --line-number
options.
The --colors
(note the plural form) option is useful to customize colors and style used for matching text, line numbers, etc. A common usage is to highlight multiple terms in different colors. See manual for complete details.
Match whole word or line
$ # this matches 'par' anywhere in the line
$ printf 'par value\nheir apparent\n' | rg 'par'
par value
heir apparent
$ # this matches 'par' only as a whole word
$ # word character means any alphabet, digit or underscore characters
$ printf 'par value\nheir apparent\n' | rg -w 'par'
par value
Use -x
to display a line only if entire line satisfies the given pattern.
$ # this matches 'my book' anywhere in the line
$ printf 'see my book list\nmy book\n' | rg 'my book'
see my book list
my book
$ # this matches 'my book' only if no other characters are present
$ printf 'see my book list\nmy book\n' | rg -x 'my book'
my book
$ # counting empty lines
$ rg -cx '' programming_quotes.txt
3
The -f
and -x
options can be combined to get common lines between two files or the difference when -v
is used as well. Add -F
as well depending on whether literal or regular expressions matching is needed.
$ cat colors_1
teal
light blue
brown
yellow
$ cat colors_2
blue
black
dark green
yellow
$ # common lines between two files
$ rg -Fxf colors_1 colors_2
4:yellow
$ # lines present in colors_2 but not in colors_1
$ rg -Fvxf colors_1 colors_2
1:blue
2:black
3:dark green
$ # lines present in colors_1 but not in colors_2
$ rg -Fvxf colors_2 colors_1
1:teal
2:light blue
3:brown
Extract only matching portion
$ rg -o -e 'twice' -e 'hard' programming_quotes.txt
1:twice
1:hard
11:hard
$ # -c only gives count of matching lines
$ rg -c 'in' programming_quotes.txt
8
$ # add -o to get total count of matches (differs from GNU grep)
$ # can also use --count-matches option instead of -co
$ rg -co 'in' programming_quotes.txt
13
Context matching
$ cat context.txt
wheat
roti
bread
blue
toy
flower
sand stone
light blue
flower
sky
water
dark red
ruby
blood
evening sky
rose
language
english
hindi
spanish
tamil
programming language
python
kotlin
ruby
Use -A
and -B
to display lines after and before matching lines.
$ # show lines containing 'blue' and two lines after such lines
$ # for multiple matches, -- is added between the results
$ # prefix is : for matching lines and - for relative lines
$ rg -A2 'blue' context.txt
5:blue
6- toy
7- flower
--
9:light blue
10- flower
11- sky
$ # show lines containing 'bread' and two lines before such lines
$ rg -B2 'bread' context.txt
1-wheat
2- roti
3: bread
Use -C
to display lines around the matching ones.
$ # same as: rg -A1 -B1 'sky' context.txt
$ rg -C1 'sky' context.txt
10- flower
11: sky
12- water
--
15- blood
16: evening sky
17- rose
$ rg -A1 -B2 'sky' context.txt
9-light blue
10- flower
11: sky
12- water
--
14- ruby
15- blood
16: evening sky
17- rose
The separator --
won't be added if two or more groups of matching lines have overlapping lines or are next to each other in input file.
$ # the two groups are next to each other here
$ rg -C1 'flower' context.txt
6- toy
7: flower
8- sand stone
9-light blue
10: flower
11- sky
$ # example for overlapping case
$ # last line of 1st group overlaps with matching line of 2nd group
$ rg -A4 'blue' context.txt
5:blue
6- toy
7- flower
8- sand stone
9:light blue
10- flower
11- sky
12- water
13-dark red
Use --context-separator
to change the default separator --
to something else. You can also use escape sequences like \t
, \n
, etc as part of the separator.
$ seq 29 | rg --context-separator='*****' -A1 '3'
3
4
*****
13
14
*****
23
24
You cannot use --context-separator=''
to display only the matches without any separator as a newline is always added in addition to the given string. Use --no-context-separator
for such cases.
$ seq 29 | rg --no-context-separator -A1 '3'
3
4
13
14
23
24
Scripting options
While writing scripts, sometimes you just need to know if a file contains the pattern and act based on exit status of the command. Instead of usual workarounds like redirecting output to /dev/null
you can use the -q
option. This will avoid printing anything on stdout
and also provides speed benefit as rg
would stop processing as soon as the given condition is satisfied.
$ cat find.md
The find command is more versatile than recursive options and
and extended globs. Apart from searching based on filename, it
has provisions to match based on the the file characteristics
like size and time.
$ rg -q 'the the' find.md
$ echo $?
0
$ rg -q 'xyz' find.md
$ echo $?
1
$ rg -q 'the the' find.md && echo 'Repeated word found!'
Repeated word found!
The --no-messages
option will suppress error messages that are intended for stderr
.
$ # when file doesn't exist
$ rg 'in' xyz.txt
xyz.txt: No such file or directory (os error 2)
$ rg --no-messages 'in' xyz.txt
$ echo $?
2
$ # when sufficient permission is not available
$ touch foo.txt
$ chmod -r foo.txt
$ rg 'rose' foo.txt
foo.txt: Permission denied (os error 13)
$ rg --no-messages 'rose' foo.txt
$ echo $?
2
Errors regarding regular expressions and invalid options will be on stderr
even when the --no-messages
option is used.
$ rg --no-messages 'a(' find.md
regex parse error:
a(
^
error: unclosed group
$ rg --no-messages 'a(' find.md 2> /dev/null
$ echo $?
2
Byte offset
$ # zero-based offset for starting line of each match
$ # if line number prefix is also active, it will be before byte offset
$ rg -Nb 'is' find.md
0:The find command is more versatile than recursive options and
125:has provisions to match based on the the file characteristics
$ # offset for start of matching portion instead of line
$ rg -Nob 'is' find.md
17:is
133:is
180:is