What grep Does
The grep command searches one or more files (or the output of another command) for lines that match a pattern, and prints each matching line to standard output. If no file is specified, grep reads from standard input.
The name stands for globally search for a regular expression and print — a reference to the equivalent operation in the ed line editor.
The most common use is simple: give grep a word or phrase and it returns every line that contains it.
grep error /var/log/syslog
grep ‘disk full’ /var/adm/messages
When more than one file is given, grep prefixes each matching line with the filename so you know where the match came from.
Basic Syntax
grep [flags] pattern [file …]
The pattern is a regular expression (see the section below). Special shell characters such as $ * [ | ^ ( ) \ must be quoted to prevent the shell interpreting them before grep sees them. As a general rule, put the pattern in single quotes:
grep ‘out of memory’ /var/adm/messages
Essential Flags
-v: Invert the match
-v prints every line that does not match the pattern. This is useful for filtering out noise — comment lines, blank lines, or entries you already know about.
grep -v ‘^#’ /etc/services # skip comment lines
grep -v ‘^$’ report.txt # skip blank lines
grep -v DEBUG /var/log/app.log # hide debug entries
-i: Ignore case
-i makes the match case-insensitive. Error, ERROR, and error all match the pattern error when -i is given.
grep -i ‘failed’ /var/adm/messages
grep -i ‘root’ /etc/passwd
-c: Count matching lines
-c suppresses normal output and instead prints a count of how many lines matched. When multiple files are given, each filename is listed with its count.
grep -c ‘error’ /var/adm/messages
grep -c ‘FAILED’ /var/log/auth.log /var/log/syslog
This is often more useful than counting lines yourself with wc -l, because it counts lines, not occurrences — a line with two matches is still counted once.
-l: List filenames only
-l suppresses normal output and prints only the names of files that contain at least one match, one per line. This is ideal for finding which files in a tree contain a particular string without being swamped by the matching lines themselves.
grep -rl ‘PermitRootLogin’ /etc # find all config files mentioning this
grep -l ‘TODO’ *.c # find source files with TODO comments
Note: -l stops searching a file as soon as the first match is found, so it is faster than a normal grep over large files.
-n: Show line numbers
-n prefixes each matching line with its line number within the file. Useful when you need to go back and edit the file at the right location.
grep -n ‘MaxInstances’ /etc/ftpd.conf
-r + -R: Recursive search
-r searches all files under a directory, descending into subdirectories. -R does the same but also follows symbolic links to directories.
grep -r ‘connection refused’ /var/log
grep -rl ‘passwd’ /etc
-w: Whole word match
-w restricts matches to complete words. The pattern must be surrounded by non-word characters (spaces, punctuation, start/end of line). This prevents log matching login or syslog.
grep -w ‘log’ /var/adm/messages
-s: Suppress error messages
-s silences the errors grep would normally produce for files that don’t exist or can’t be read. This is useful in scripts where missing files are expected.
-h: Suppress filenames
When multiple files are given, grep normally prefixes each line with the filename. -h suppresses that prefix, giving clean output suitable for piping.
grep -h ‘error’ /var/log/*.log | sort | uniq -c
Context Lines: -A, -B, and -C
The -A, -B, and -C flags are found in BSD, GNU and other systems but not AIX. They are documented here because they are widely used systems and in cross-platform scripts. If you need this behaviour on AIX, the workaround is shown below.
On GNU/Linux systems, three flags control how many surrounding lines are shown alongside each match:
| Flag | Effect |
| -A n | Show n lines After each match |
| -B n | Show n lines Before each match |
| -C n | Show n lines of Context (before and after) |
These are invaluable when reading log files, because a single matching line rarely tells the whole story — you need to see what led up to an error and what followed it.
# Linux only — not available on AIX grep
grep -A 3 ‘FAILED LOGIN’ /var/log/auth.log
grep -B 2 -A 5 ‘panic’ /var/log/syslog
grep -C 4 ‘out of memory’ /var/adm/messages
AIX workaround
On AIX, the -p flag prints the whole paragraph (text block separated by blank lines) that contains the match, which sometimes gives enough context. For precise line-count context, pipe through awk instead:
# Print 3 lines after each match using awk
grep -n ‘panic’ /var/adm/messages | awk -F: ‘
{ n=$1; for(i=n; i<=n+3; i++) print i }’ | xargs -I{} sed -n ‘{}p’ /var/adm/messages
Regular Expression Matching
By default, grep treats its pattern as a Basic Regular Expression (BRE). You do not need to use regular expressions — a plain word or phrase works fine. But knowing the basics lets you write much more powerful searches.
Anchors
Anchors match a position in the line rather than a character.
| Pattern | Meaning |
| ^word | Line begins with word |
| word$ | Line ends with word |
| ^word$ | Line contains exactly word and nothing else |
| ^$ | Empty line |
grep ‘^root’ /etc/passwd # lines starting with root
grep ‘sh$’ /etc/passwd # lines ending with sh
grep ‘^$’ report.txt # blank lines
The Dot: any character
. (dot) matches any single character except a newline.
grep ‘f.o’ file # matches foo, fao, f1o, f o, etc.
Character Classes
[…] matches any one of the characters listed inside the brackets.
| Pattern | Meaning |
| [aeiou] | Any vowel |
| [a-z] | Any lowercase letter |
| [A-Z] | Any uppercase letter |
| [0-9] | Any digit |
| [^0-9] | Any character that is not a digit (^ inside brackets negates) |
| [a-zA-Z] | Any letter (upper or lower) |
grep ‘^[a-zA-Z]’ pgm.s # lines beginning with a letter
grep ‘[0-9]’ report.txt # lines containing any digit
Repetition
| Symbol | Meaning |
| * | Zero or more of the preceding character or group |
| \+ | One or more (BRE syntax — backslash required) |
| \? | Zero or one (optional) |
grep ‘err*or’ file # matches eror, error, errror …
grep ‘colou\?r’ file # matches color or colour
Escaping Special Characters
To search for a literal character that grep would otherwise treat as special (such as . or $), precede it with a backslash. Because the shell also interprets backslashes, you may need to double them or use single quotes:
grep ‘\$HOME’ script.sh # literal dollar sign
grep ‘192\.168’ hosts # literal dots in an IP address
Filtering Command Output
grep is very useful for filtering the output of a another command to find the lines you want.
Checking running processes
ps -ef | grep httpd # is the web server running?
ps -ef | grep -v grep # exclude the grep process itself
ps -ef | grep -i java # case-insensitive process search
The grep -v grep trick is necessary because ps -ef | grep httpd will always match its own grep process as well as the real target.
Checking network connections
netstat -an | grep LISTEN # show all listening ports
netstat -an | grep ‘:80 ‘ # is anything on port 80?
netstat -an | grep ESTABLISHED # active connections
Filtering filesystem and disk output
df -g | grep -v ‘Filesystem’ # disk usage, skip header line
lsdev -Cc disk | grep -i hdisk # list disk devices
mount | grep ‘/data’ # is /data mounted?
Inspecting installed filesets
lslpp -l | grep -i openssh # is openssh installed?
lslpp -l | grep COMMITTED # all committed filesets
User and group queries
grep ‘^frank’ /etc/passwd # frank’s passwd entry
grep -i ‘frank’ /etc/group # groups frank belongs to
who | grep frank # is frank logged in?
Searching Log Files
Log files on AIX are typically found under /var/adm/ and /var/log/ . At least on AIX systems that don’t store them in the ODM. The principles below apply equally to application logs wherever they are located, or indeed if you dump them from the ODM using the errpt command.
Finding errors and warnings
grep -i ‘error’ /var/adm/messages
grep -i ‘warn\|error\|fail’ /var/adm/messages
grep -c ‘error’ /var/adm/messages # how many error lines today?
Searching for a specific date or time
AIX syslog entries begin with a timestamp. You can anchor a search on the month and day:
grep ‘^Jun 8’ /var/adm/messages # all entries for 8 June
grep ‘^Jun 8 14:’ /var/adm/messages # entries for 14:xx on 8 June
Tracking a specific process or daemon
grep ‘sshd’ /var/adm/messages
grep ‘cron\[‘ /var/adm/messages # cron log entries (bracket is literal)
grep -i ‘lvmmon’ /var/adm/messages # LVM monitor messages
Finding login failures
grep -i ‘failed\|invalid\|illegal’ /var/adm/messages
grep ‘authentication failure’ /var/log/auth.log
Combining grep with other tools
Pipelines let you refine searches progressively or reformat the output:
# count errors per hour
grep ‘error’ /var/adm/messages | awk ‘{print $3}’ | cut -c1-2 | sort | uniq -c
# unique error messages, sorted by frequency
grep -i ‘error’ /var/adm/messages | sort | uniq -c | sort -rn | head -20
# errors from the last 100 lines of a log
tail -100 /var/adm/messages | grep -i error
# watch a log live and highlight errors
tail -f /var/adm/messages | grep –line-buffered -i error
Exit Status
grep’s exit status is useful in scripts for testing whether something exists:
| Exit code | Meaning |
| 0 | At least one matching line was found |
| 1 | No matching lines were found |
| >1 | A syntax error occurred, or a file was inaccessible |
# Test whether a user account exists
if grep -q ‘^frank:’ /etc/passwd; then
echo ‘Account exists’
fi
# -q suppresses all output — use purely for the exit code
grep -qs ‘error’ /var/adm/messages && echo ‘Errors found’
Quick Reference
grep [flags] pattern [file …]
Key flags:
-v Invert: print non-matching lines
-i Case-insensitive matching
-c Print count of matching lines
-l Print filenames only (not matching lines)
-n Prefix lines with line number
-r / -R Recursive (R also follows symlinks)
-w Whole-word match
-h Suppress filename prefix
-s Suppress file-not-found errors
-q Quiet: no output, use exit code only
-p Print whole paragraph containing match
-A n [BSD/GNU Only] Print n lines After match
-B n [BSD/GNU] Print n lines Before match
-C n [BSD/GNU] Print n lines Context around match
Pattern anchors:
^ Start of line
$ End of line
. Any single character
[abc] Any of a, b, or c
[^abc] Any character except a, b, or c
[a-z] Range of characters
* Zero or more of preceding
\+ One or more of preceding (BRE)
\? Zero or one of preceding (BRE)
\ Escape next character

