Formatting Flags
rg outputs human-readable grouped results by default. These flags reshape the output for different consumers: scripts, editors, and monitoring pipelines.
Line Numbers (-n / -N)
rg includes line numbers by default. The flags let you toggle:
rg -n "TODO" src/ # (default) with line numbers
rg -N "TODO" src/ # without line numbers
Only Filenames (-l)
The most common output shaping flag. Returns only the names of files with at least one match, then stops reading each file:
# Which files contain "FIXME"?
rg -l "FIXME" src/
# Pass list to xargs for bulk operations
rg -l "old_api_v1" . | xargs sed -i 's/old_api_v1/new_api_v2/g'
Count Matches Per File (-c)
# How many TODOs are in each file?
rg -c "TODO" src/
# Output:
# src/app.py:3
# src/utils.py:1
# src/models.py:7
Print Only the Match (-o)
Like grep -o — discard the surrounding line and print only the exact matched substring. One match per line:
# Extract all IP addresses
rg -o "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" access.log | sort -u
# Extract all HTTP status codes
rg -o "HTTP/[0-9\.]+ \K[0-9]{3}" access.log | sort | uniq -c
JSON Output (--json)
rg --json outputs newline-delimited JSON (NDJSON). Every match, begin, end, and summary event is a JSON object — ideal for programmatic consumption.
rg --json "ERROR" app.log | jq 'select(.type == "match") | .data.lines.text'
Fields include: path, line_number, absolute_offset, lines, submatches.
Vimgrep Format (--vimgrep)
Outputs file:line:col:text format, which is directly compatible with Vim's copen quickfix list:
rg --vimgrep "TODO" src/ > /tmp/todo.txt
# In Vim:
# :cfile /tmp/todo.txt
# :copen
No Heading (--no-heading)
By default rg groups results under a filename header. Use --no-heading to get the traditional grep-style file:line:match format — required when piping to tools that expect that format.
rg --no-heading "pattern" . | cut -d: -f1 | sort -u