Skip to main content

ag — The Silver Searcher (Code Search Tool)

Introduction​

ag (The Silver Searcher) is a fast text and code search tool designed for developers and operators who need quick, project-aware searching. It is often compared to ack and rg.

Tool Snapshot
  • Core Function: High-speed recursive text search in codebases.
  • Primary Benefit: Faster than grep by skipping ignored/binary files by default.
  • Where to Use: Large source code directories (e.g., WordPress plugins/themes).
  • Logic: Respects .gitignore and .agignore files to filter noise.

Key characteristics:

  • Optimized for searching source code quickly
  • Skips binary files by default
  • Respects .gitignore and common ignore rules (reduces noise in repositories)
  • Provides convenient file type filters (--php, --js, --css, etc.)
  • Works well in WordPress environments for scanning plugins, themes, configs, and logs

Use ag when you want a fast “search in project” experience with sensible defaults and minimal manual filtering.

Installation​

Debian/Ubuntu:

sudo apt update
sudo apt install -y silversearcher-ag

Verify:

ag --version

Syntax & Expression Rules​

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

ag [OPTIONS] PATTERN [PATH]
  • [OPTIONS]: Flags to modify matching rules or output (e.g., -i, --php).
  • [PATTERN]: The text or regex pattern to search for.
  • [PATH]: File or directory to search (defaults to current directory if omitted).

Options Reference​

Basic Searching​

OptionDescription
-iCase-insensitive search
-sCase-sensitive search (default behavior)
-wMatch whole words only
-QLiteral search (treat pattern as plain text, no regex)
-vInvert match (show non-matching lines)
-qQuiet mode (no output, exit code only)

Output Control​

OptionDescription
--
-nShow line numbers
-HShow filename (useful when searching a single file)
-cCount matches (usually per file)
-lList filenames with matches only
-oPrint only the matched part of the line
-m NUMStop after NUM matches

Context Control​

OptionDescription
---
-A NUMShow NUM lines after match
-B NUMShow NUM lines before match
-C NUMShow NUM lines before and after match

File Handling​

OptionDescription
--
--php, --js, --cssRestrict search to file type
--ignore-dir=DIRExclude a directory
--ignore=PATTERNExclude files matching pattern
-aSearch all files (including binary)
-uSearch ignored and hidden files (bypass ignore rules more aggressively)

Regex and Matching Controls​

OptionDescription
---
-G REGEXSearch only files whose names match REGEX
-f FILERead patterns from FILE (one per line)

Utility​

OptionDescription
---
--depth NUMLimit recursion depth
--statsPrint summary stats after search
--versionPrint version
--helpShow help

Pattern Matching Notes​

ag supports regular expressions by default.

  • Use plain text patterns for simple matching

  • Use anchors for precise placement:

    • ^pattern start of line
    • pattern$ end of line
  • Use -Q to treat the pattern literally (recommended when the pattern contains regex characters like +, ., *, ?, (, ))

WordPress / VPS Examples (30)​

Assumptions:

  • WordPress root: /var/www/html
  • Plugins: /var/www/html/wp-content/plugins
  • Themes: /var/www/html/wp-content/themes
  • Logs: /var/log/nginx/error.log

1. Search for DB credentials in wp-config​

ag "DB_NAME" wp-config.php

Expected output:

3:define('DB_NAME', 'wpdb');

2. Case-insensitive search in logs​

ag -i "error" /var/log/nginx/error.log

Expected output:

2025/10/03 [ERROR] Connection refused

3. Search only PHP files​

ag --php "wp_enqueue_script" wp-content/

Expected output:

functions.php:12:wp_enqueue_script('theme-js', ...);

4. Search in CSS files​

ag --css "color:" wp-content/themes/

Expected output:

style.css:18:color: #444;

5. List filenames with matches only​

ag -l "add_action" wp-content/plugins/

Expected output:

plugin.php
hooks.php

6. Count matches​

ag -c "define" wp-config.php

Expected output:

wp-config.php:8

7. Show line numbers​

ag -n "DB_USER" wp-config.php

Expected output:

25:define('DB_USER', 'wpuser');

8. Match whole word​

ag -w "admin" users.txt

Expected output:

admin

9. Invert match​

ag -v "cache" plugins.txt

Expected output:

akismet
seo-plugin

10. Match at beginning of line​

ag "^define" wp-config.php

Expected output:

define('DB_NAME', 'wpdb');

11. Match at end of line​

ag "php$" filelist.txt

Expected output:

index.php
wp-config.php

12. Literal search (no regex interpretation)​

ag -Q "a+b" file.txt

Expected output:

a+b

13. Regex OR pattern​

ag "cat|dog" animals.txt

Expected output:

cat
dog

14. Show 2 lines of context around match​

ag -C2 "DB_USER" wp-config.php

Expected output:

/** Database settings */
define('DB_NAME', 'wpdb');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'secret');

15. Recursive search ignoring directory​

ag "define" wp-content/ --ignore-dir=cache

Expected output:

functions.php:3:define('THEME_VERSION', '1.0');

16. Search hidden / ignored files​

ag -u "DB_PASSWORD" /

Expected output:

.env:2:DB_PASSWORD=secret123

17. Search all files (including binaries)​

ag -a "<?php" backups/

Expected output (example):

backup.tar.gz: contains <?php code

18. Stop after 1 match​

ag -m1 "error" error.log

Expected output:

[error] File not found

19. Extract only match (URLs)​

ag -o "https://[a-zA-Z0-9./]*" index.php

Expected output:

https://example.com

20. Limit search to filenames via regex​

ag -G ".*\.php" "function" wp-content/

Expected output:

plugin.php:23:function custom_func() {

21. Search suspicious eval usage​

ag "eval\(" wp-content/plugins/

Expected output:

bad-plugin.php:45:eval(base64_decode(...));

22. Multiple patterns (repeat -e)​

ag -e "error" -e "warning" logs/

Expected output:

[error] file missing
[warning] deprecated function
ag "define" wp-config.php --stats

Expected output (example):

1 matches
1 files searched

24. Limit recursion depth​

ag "pattern" --depth 2 wp-content/

Expected result: searches only 2 directory levels deep.

25. Find suspicious base64_decode usage​

ag "base64_decode" wp-content/

Expected output:

malicious.php:40:eval(base64_decode(...));

26. Search in JavaScript only​

ag --js "console.log" wp-content/themes/

Expected output:

main.js:12:console.log("Debugging");

27. Search CSS font-size rules​

ag --css "font-size" wp-content/themes/

Expected output:

style.css:23:font-size: 16px;

28. Search comments in PHP​

ag "^//" functions.php

Expected output:

// Theme setup
// Custom function

29. Search inside SQL dump​

ag "CREATE TABLE" backup.sql

Expected output:

CREATE TABLE `wp_users` (
CREATE TABLE `wp_posts` (

30. Quiet mode (exit code only)​

ag -q "DB_PASSWORD" wp-config.php && echo "Found"

Expected output:

Found

Benefits​

  • Fast codebase searching with sensible defaults
  • Respects .gitignore to reduce noise
  • Skips binary files by default
  • Useful file type filters for common languages
  • Practical for WordPress troubleshooting and security scans

Best Practices​

  • Use --php, --js, --css to avoid scanning irrelevant file types.
  • Use -G to narrow by filename patterns when type filters are not enough.
  • Use -Q for literal searches when patterns contain regex characters.
  • Use -C, -A, -B for context during debugging.
  • Use -u during security audits when hidden/ignored files must be included.
  • Avoid -a unless required; searching binaries can generate noisy results.

Troubleshooting Matrix​

ProblemLikely CauseFix
-
No resultsCase mismatchAdd -i
Too many resultsBroad searchUse --php, --js, --css or -G
Missing resultsIgnored by defaultAdd -u
Binary file skippedDefault behaviorAdd -a
Regex unexpected behaviorPattern treated as regexUse -Q for literal

Cheat Sheet​

ag "pattern" dir/
ag -i "error" error.log
ag --php "function" /var/www/html
ag -l "add_action" wp-content/plugins/
ag -c "define" wp-config.php
ag -A2 "pattern" file
ag -C2 "pattern" file
ag -o "https://.*" file
ag -u "DB_PASSWORD" /
ag -Q "a+b" file.txt

Mini Quiz​

  1. What makes ag faster than traditional grep in codebases?
  2. How do you search only in PHP files?
  3. Which option includes hidden or ignored files?
  4. How do you show 2 lines after a match?
  5. Which option treats the pattern as a literal string?
  6. What is the purpose of -G?
  7. When should -a be avoided?
  8. Which option lists only filenames with matches?
  9. How do you stop after the first match?
  10. What option prints only the matched text?