![]() Searching for “PATTERNS” or “regex” in grep --help | |
Release Status | Maintained |
---|---|
Last Release | 3.12 (2025-04-10) |
Language(s) | C |
Developer(s) | GNU grep: GNU Project, et al. |
Website | https://www.gnu.org/software/grep/ |
grep
(global regular expression print) is a fundamental command-line utility in Unix-like operating systems, designed to “[search] plain-text data sets for lines matching a regular expression”[1][2].
History
Developed by Ken Thompson at Bell Labs in 1973 for Unix, grep's creation stemmed from Thompson's need to analyse text in The Federalist Papers for authorship attribution. To handle large files efficiently, he extracted the regex code from the ed text editor into a standalone tool. He named the tool grep because in ed, the command g/re/p
prints out all lines that match the pattern re
.[2]
Usage
Basic Search
From grep --help
:
Usage: grep [OPTION]... PATTERNS [FILE]... Search for PATTERNS in each FILE. Example: grep -i 'hello world' menu.h main.c PATTERNS can contain multiple patterns separated by newlines.
The most basic usage is
cat log.txt | grep "error"
This feeds the content of the log.txt
file into grep, which finds all lines with the text “error”.
However, grep itself can read files directly, so it is better to just do:
grep "error" log.txt
The most common flags are:
-i, --ignore-case ignore case distinctions in patterns and data -w, --word-regexp match only whole words -r, --recursive like --directories=recurse -n, --line-number print line number with output lines
For example,
grep -i warning log.txt
matcheswarning
,WARNING
,Warning
, etc.grep -w berry
matchesberry
but notstrawberry
orblueberry
.grep -r admin /etc/
searches foradmin
in all files inside the/etc/
directory.
Extended Regular Expressions
The -E
flag enables extended regular expressions (ERE), while the lack of so only allows basic regular expressions (BRE), a very small subset of what most modern regex implementations provide:[3]
$ grep --help | grep -- '--' | head -n3 # `--` to tell grep to stop processing flags
-E, --extended-regexp PATTERNS are extended regular expressions
-F, --fixed-strings PATTERNS are strings
-G, --basic-regexp PATTERNS are basic regular expressions
$ grep --help | grep '^\s+--'
$ grep --help | grep -E '^\s+--' | head -n3
--no-ignore-case do not ignore case distinctions (default)
--help display this help text and exit
--line-buffered flush output on every line
Examples
Finding Python Function Calls
In a Python codebase, we can find all calls to functions under the subprocess
module
with shell=True
:
$ grep -r --include='*.py' -nHE 'subprocess\.\w+\([^)]*shell=True' ./driver.py:69: return subprocess.call("lspci | grep -q -i NVIDIA", shell=True) == 0 ./driver.py:202: return subprocess.call("lspci | grep -q -i Network | grep -q -i Broadcom", shell=True) == 0 ./driver.py:211: return subprocess.call("lspci | grep -q -i Bluetooth | grep -q -i Broadcom", shell=True) == 0 ./util.py:38: proc = subprocess.Popen(f"chroot {chroot} /tmp/stellar-payload.sh", shell=True) ./util.py:63: # proc = subprocess.Popen(payload, shell=True) ./util.py:66: proc = subprocess.Popen(f"pkexec {tmpfile}", shell=True)
(This is run on the Ultramarine stellar codebase)
We can breakdown the flags used in this example:
-r
: find files recursively (by default in the current working directory)--include='*.py'
: only examine Python files-n
: show line numbers-H
: show file name-E
: enable ERE
We can divide the pattern subprocess\.\w+\([^)]*shell=True
into many parts:
subprocess
matches the string “subprocess” literally;\.
matches the full stop literally;\w+
matches word characters one or more times, where a word character (\w
) is any letter, digit or underscore[4];\(
matches for an open parenthesis(
literally;[^)]*
is an inverse character group and matches any characters that are not the closing parenthesis)
zero or more times; andshell=True
matches the string “shell=True” literally.
Finding Code Files with TODOs and FIXMEs
We can list out code files that contains both the word “FIXME” and “TODO”. For a Rust project:
$ grep -rlZ 'FIXME' --include='*.rs' . | xargs -0 grep -l 'TODO' ./src/pages/_15_installing.rs ./src/main.rs
Flags:
-r
: find files recursively (by default in the current working directory)-l
: output matching files' names only-Z
: instead of a new line character, print out a null character after each filename--include='*.rs'
: only examine Rust files
In this example, the first command outputs the filenames with null separates, then xargs is used to feed the filenames into the second grep command, which searches for “TODO”s in those files.
Extracting All Unique Public IPv4 Addresses from Log Files
We can extract all the unique IPv4 addresses from a directory of log files,
but exclude any private IP addresses, such as 10.x.x.x
/ 192.168.x.x
:
grep -rhoE '([0-9]{1,3}\.){3}[0-9]{1,3}' /path/to/logs | sort -u | grep -vE '^10\.|^192\.168\.'
Flags:
-r
: find files recursively-h
: suppress printing of filenames-o
: show only matching part of line-E
: enable ERE-v
: select non-matching lines
For the first pattern:
[0-9]
matches the digits (0 to 9 on the ASCII table includes all digits), and{1,3}
specifies the length must be between 1 and 3; and([0-9]{1,3}\.){3}
matches exactly 3 times the above followed by a full stop.
For the second pattern:
^10\.
matches for lines starting with10.
;^192\.168\.
matches for lines starting with192.168.
; and|
(which indicates “or”) allows matching for the regex specified on the left or the right.
Due to the invert flag (-v
), if a line matches the second pattern, it is excluded, and other lines are printed instead.
Alternatives
Faster implementations of grep such as ripgrep (rg
) and hypergrep (hgrep
) are usually available in mainstream package repositories, but are not bug-for-bug compatible with GNU grep, and usually not pre-installed on most distributions.
The agrep
tool (approximate grep) can find matches even if the pattern is not matched exactly[5].
See Also
References
- ↑ Wikipedia Snapshot for grep, knot.math.usf.edu, 2012 (Accessed 2025-06-21)
- ↑ 2.0 2.1 grep, Wikipedia, 2025 (Accessed 2025-06-21)
- ↑ GNU Grep 3.12, gnu.org, 2025 (Accessed: 2025-06-21)
- ↑ Understanding \w and Its Counterpart \W in Regex, RegexRoo.com, 2025 (Accessed: 2025-06-21)
- ↑ agrep, Wikipedia, 2025 (Accessed: 2025-06-21)