grep-like commands on unix-like OSes are great. They come pre-installed. In fact, a search using grep is faster than
the search on your IDE when there is no code index.
But, one key pain when using grep for searching in your source code or configuration files? A grep -r scans all
files (including binary files 🫣) and not just source code files, making it slow. Sometimes, very slow.
scgrep, which stands for 'source code grep', is a lightweight CLI tool that wraps your system's
grep command and runs it only on source code files. Flags and pattern you pass to scgrep are passed as is to the
underlying grep command, making it almost 100% compatible with grep. So, no need to learn a new syntax!
scgrep runs not one but multiple grep commands in parallel, making it significantly faster on large directories.
- Install Go version at least 1.25
- Run command:
go install github.com/m-manu/scgrep@latest
- Add following line in your
.bashrc/.zshrcfile:export PATH="$PATH:$HOME/go/bin"
# Below is equivalent to searching for string "LinkedHashSet" in the current directory and its subdirectories
# It's equivalent to `grep -r LinkedHashSet` (but traverses only source code files)
scgrep "LinkedHashSet"
# Below is same as above but passes `--color` flag to the underlying `grep` (Colorized output)
scgrep --color "LinkedHashSet"
# Below is same as above but passes `--color` and `-iw` flags to the underlying `grep` (Colorized output, case-insensitive, whole word only)
scgrep --color -iw "todo"scgrep provides a specific flag --directories that lets you specify multiple directories
# Searches `./src/main` and `./src/test` for `LinkedHashSet`, with color.
# Both roots are validated as readable directories before scanning starts.
scgrep --color "LinkedHashSet" --directories ./src/main ./src/testNote: Order matters for --directories (everything after --directories is treated as a directory path)
scgrep -- -weird-patternA bare -- ends grep's own flag parsing. Useful when the pattern starts with a -.
scgrep --grep-cmd fgrep "LinkedHashSet"
scgrep --grep-cmd=/usr/bin/grep -n "main"If the chosen command is not on PATH (or the absolute path does not exist), scgrep exits with code 6 and does not
run a search.
scgrep doesn't reimplement the logic to ignore files in .gitignore in a git repo. It relies on underlying git
command instead. If git is not installed or is not in $PATH, scgrep uses its default source-code awareness
behavior.
These tools reimplement the grep logic, in their own ways. In many cases, they're not compatible with grep.
scgrep acts as a thin wrapper and lets you use your own grep and just adds source-code awareness.
scgrep command traverses file tree with source code awareness in following ways:
- Scans for files with known source code and configuration file extensions (case-insensitive)
- e.g.
.java,.go,.py,.ymletc. (see full list)
- e.g.
- Scans for files with certain names (case-sensitive)
- e.g.
postinst,Dockerfileetc. (see full list)
- e.g.
- Skips scanning certain directories (case-sensitive)
- e.g.
.git,.idea,.gradleetc. (see full list)
- e.g.
- Skips scanning certain directories with specific peer files (case-sensitive)
- e.g. skip
buildsubdirectory whenbuild.gradleexists in the same directory etc. (see full list)
- e.g. skip
Additionally, when git is available and the search root is inside a Git working tree, scgrep respects the
.gitignore file (via git ls-files).
Flags such as -r, -R and --recursive get ignored. scgrep passes these flags as is to the underlying grep,
which ignores these flags because underlying grep receives list of file names (not directories) as arguments.
e.g. Output of scgrep -r -i "TODO" would be same as scgrep -i "TODO"
Yes, just a couple:
- Options
--directories,--grep-cmd,--version,-h/--helpthatscgrepconsumes directly and does not pass togrep - A
-Hit adds togrepwhen you have not already requested filenames (This is required to view the matching file names)