Grep: displaying lines before and after a match on Linux

Linux 3 min read

The grep command prints the lines from a file or the output of another command in which the searched text appears. However, when analysing log files, the hit itself is often not enough: the lines before and after a PHP error or a failed login show what led to the error and what happened afterwards. This is what context switches are for.

grep 'valami' /path/to/file.log

Lines before the result: -B

The number of lines specified after the -B (before) switch is also displayed before the search results:

grep -B 5 'valami' /path/to/file.log

This displays 5 lines before each result.

Lines following the search results: -A

The -A (after) switch displays the lines following the search result:

grep -A 3 'valami' /path/to/file.log

This displays three lines after each result. It is useful, for example, with multi-line error messages (stack traces), where the key information is found below the error line.

Lines on both sides: -C

If you need the same number of lines before and after the match, use the -C (context) switch:

grep -C 2 'valami' /path/to/file.log

For a different number of lines, both switches can be used together: the command grep -B 5 -A 2 'valami' fajl.log prints the 5 lines before the match and the 2 lines after it.

If multiple matches occur adjacent to one another, grep combines them into a single block, whilst separating distinct blocks with a -- line. In a 30-line test file, for the matches on lines 10, 13 and 25, the command grep -n -C 2 produced the following output (the line number is followed by : to indicate the match, and - to indicate the surrounding line):

8-sor 8
9-sor 9
10:sor 10 HIBA
11-sor 11
12-sor 12
13:sor 13 HIBA
14-sor 14
15-sor 15
--
23-sor 23
24-sor 24
25:sor 25 HIBA
26-sor 26
27-sor 27
  • --color=auto: highlights the match in the output (the --colour syntax also works). This is enabled by default in many distributions.
  • -n: prints the line number, making it easy to locate the position in the file.
  • -i: is not case-sensitive.
  • -r searches recursively within a folder and its subfolders.
  • -v: displays the lines that do not match.
  • -E: uses an extended regular expression, for example grep -E 'error|warning'.

A complete example that searches using a line number, highlighting, and the 5 lines before and 2 lines after the match:

grep -n --color=auto -B 5 -A 2 'Fatal error' /var/www/oldal/error_log

Practical examples

# Egy IP-cím kérései az Apache naplójában, a környező sorokkal
grep -C 3 '203.0.113.25' /var/log/httpd/access_log

# Sikertelen SSH-bejelentkezések AlmaLinux/Rocky Linux alatt
grep -B 2 'Failed password' /var/log/secure

# Egy szolgáltatás naplója systemd alatt, a grep-pel szűrve
journalctl -u nginx --no-pager | grep -A 5 'error'

# Régi, elforgatott naplókban keresés (tömörített és tömörítetlen fájlokban is)
zgrep -C 3 'valami' /var/log/messages-*

On AlmaLinux and Rocky Linux, logrotate does not compress by default (#compress in the /etc/logrotate.conf file): old logs are uncompressed files in the format messages-20261020, so there would be no matches for the *.gz pattern. On Debian and Ubuntu, rotated logs typically have a .gz extension. zgrep searches for both types; in the test, it found the lines in both an uncompressed file and a .gz file.

On Debian and Ubuntu, the Apache log is located in /var/log/apache2/, whilst the authentication log is in the /var/log/auth.log file. Our article on journalctl and /var/log covers the location and reading of log files, whilst our guide on locating and deleting large error_log files deals with managing error logs that have grown too large.

Back: Linux articles (62)