Skip to main content

rg

Introduction

rg (ripgrep) is a high-performance recursive search tool designed as a modern replacement for grep. It is optimized for speed, usability, and intelligent defaults, making it ideal for searching large codebases, WordPress installations, and log directories on VPS systems.

Tool Snapshot
  • Core Function: Ultra-fast recursive search engine for file content.
  • Primary Benefit: Rust-powered speed with automatic filtering of ignored/hidden files.
  • Where to Use: Massive log analysis, malware triage, and large-scale code audits.
  • Key Feature: High-performance regex engine and JSON output support.

Unlike traditional grep, rg:

  • Searches recursively by default
  • Respects .gitignore, .ignore, and .rgignore
  • Skips hidden and binary files unless explicitly enabled
  • Uses a fast regex engine (Rust regex by default)
  • Supports advanced PCRE2 patterns (when compiled with PCRE2)
  • Can search inside compressed files
  • Provides structured JSON output for automation

For sysadmins and developers, rg is especially effective for:

  • Malware and obfuscation detection
  • Log analysis
  • Code auditing
  • Configuration troubleshooting
  • Incident response investigations

Prerequisites

  • Ubuntu/Debian or similar Linux VPS
  • SSH access
  • WordPress paths you should know:
    • /var/www/html/ → WordPress root
    • /var/www/html/wp-content/uploads/ → Media
    • /home/backups/ → Backups

Install and verify:

sudo apt install ripgrep
rg --version

Syntax & Expression Rules

The command follows a logical structure that reads almost like a sentence:

rg [OPTIONS] PATTERN [PATH...]
  • [OPTIONS]: Flags to modify search (e.g., -i for case-insensitive, -t for file type).
  • [PATTERN]: The regex or fixed string to search for.
  • [PATH]: One or more directories or files to search (defaults to current directory).

Multiple patterns

rg -e PATTERN1 -e PATTERN2 [PATH...]

Patterns from file

rg -f patterns.txt [PATH...]

Pattern Engine

  • Default engine: Rust regex (fast, safe, no catastrophic backtracking)
  • Enable PCRE2 (lookaround, backreferences) with:
rg -P 'pattern'

PCRE2 support depends on how ripgrep was compiled.

How rg Handles Scope

  • If no path is provided, rg searches the current directory.

  • If specific files are provided explicitly, ignore rules are bypassed.

  • By default:

    • Hidden files are skipped
    • Binary files are skipped
    • .gitignore rules are respected

Control filtering with:

  • --hidden
  • -u, -uu, -uuu
  • --no-ignore

Important Filters and Options

OptionDescriptionWordPress/VPS Use CaseExample
---
-FFixed string (no regex)Literal malware signaturerg -F 'base64_decode(' -t php
-iIgnore caseCase-insensitive searchrg -i logo
-SSmart caseCase-sensitive only if uppercase usedrg -S logo
-t TYPELimit by file typeOnly PHP filesrg -t php add_action
--type-listShow supported typesView available filtersrg --type-list
-g GLOBInclude/exclude via globSkip vendor directoryrg -g '!vendor/**'
--iglobCase-insensitive globMatch *.JPGrg --iglob '*.jpg'
--hiddenInclude hidden filesSearch .env filesrg --hidden token
-u/-uu/-uuuRelax ignore rulesFull forensic scanrg -uuu password
-LFollow symlinksDeployment releasesrg -L -t php add_action
--one-file-systemStay within filesystemAvoid NFS mountsrg --one-file-system error /var
-zSearch compressed filesInspect backupsrg -z ERROR /home/backups
--encodingSpecify encodingLegacy logsrg --encoding latin1 pattern
-UEnable multilineCross-line patternsrg -U 'BEGIN.*END'
--multiline-dotall. matches newlineFull block matchingrg -U --multiline-dotall 'A.*Z'

Most Important Filters (Practical Ranking)

FilterRatingWhy It Matters
----
-t TYPE5/5Massive noise reduction in codebases
-g5/5Precise include/exclude control
-F4/5Faster and safer for literal search
--hidden + -u4/5Critical for audits and incident response
-P3/5Required only for advanced regex features

Output and Action Controls

OptionPurposeExample
----
-nShow line numbersrg -n error
-HAlways show filenamerg -nH error
-lFilenames onlyrg -l base64
-cCount matches per filerg -c wp_enqueue
-vInvert matchrg -v DEBUG app.log
-oPrint only match textrg -o 'https?://\S+'
-C NUMShow contextrg -C2 ERROR
--vimgrepEditor-friendly outputrg --vimgrep TODO
--jsonStructured outputrg --json pattern
--statsShow search statsrg --stats pattern

When piping results, force consistent output:

rg -nH --color=never pattern

Benefits

  • Extremely fast recursive search
  • Smart filtering by default
  • Respects project ignore rules
  • Powerful type system for languages
  • JSON output for automation
  • Compressed file search
  • Advanced regex support (PCRE2 optional)

Best Practices

  • Narrow scope early with -t and -g.
  • Use -F for fixed strings unless regex is required.
  • Add -nH when piping to other tools.
  • Use --hidden and -uu during security audits.
  • Use -P only when you need lookaround or backreferences.
  • Combine --json with jq for structured automation.

Cheat Sheet

# Basic recursive search
rg pattern

# Force filename and line numbers
rg -nH pattern

# Fixed string search
rg -F 'literal text'

# File type filtering
rg -t php add_action

# Exclude heavy directories
rg -g '!vendor/**' -g '!node_modules/**'

# Include hidden files
rg --hidden -uu secret

# Count matches
rg -c pattern

# Show only filenames
rg -l pattern

# Context lines
rg -C3 ERROR

# PCRE2 lookbehind (if supported)
rg -P '(?<=foo)bar'

# Multiline search
rg -U --multiline-dotall 'BEGIN.*END'

# Search inside compressed backups
rg -z ERROR /home/backups

# JSON output for automation
rg --json pattern | jq .

Troubleshooting Matrix

ProblemCauseSolution
---
No resultsHidden or ignored filesAdd --hidden or -uu
No line numbers in pipeNon-TTY outputAdd -nH
Lookaround not workingPCRE2 not enabledUse -P and verify build
Globs case-sensitiveDefault glob behaviorUse --iglob
Multiline regex fails. doesn’t match newlineAdd -U --multiline-dotall
Too many resultsScope too broadAdd -t or -g filters

WordPress / VPS Examples

1. Malware triage in PHP

rg -nH -t php -g '!vendor/**' -e 'base64_decode' -e 'eval\s*\(' /var/www/html

2. Search Nginx logs for 5xx errors

rg -n 'HTTP/1\.1" 5\d\d' /var/log/nginx

3. Count enqueue usage in themes

rg -c -t php 'wp_enqueue' /var/www/html/wp-content/themes

4. Detect PHP inside uploads (suspicious)

rg -l -t php --hidden -g 'wp-content/uploads/**' .

5. Search inside compressed backups

rg -z 'DROP TABLE' /home/backups

Mini Quiz

  1. What does -uu enable compared to default search?
  2. When do you need -P?
  3. How do you exclude heavy directories?
  4. How do you search inside compressed files?
  5. Which options force filenames and line numbers when piping?