head prints the start of a file and tail prints the end. On servers, tail -f is the classic way to watch logs in real time while you reproduce a problem.
head: the first lines
head file.txt # first 10 lines
head -n 25 file.txt # first 25 lines
head -n -5 file.txt # everything except the last 5 lines
head -c 100 file.bin # first 100 bytes
head -n 3 *.csv # several files, each with a ==> name <== header
Typical uses: peek at the header of a CSV or SQL dump, or check the first lines of a config.
zcat backup.sql.gz | head -n 30 # check a compressed dump without unpacking it
tail: the last lines
tail file.log # last 10 lines
tail -n 100 file.log # last 100 lines
tail -n +20 file.txt # from line 20 to the end (skip the first 19)
tail -c 1K file.bin # last 1 KiB
tail -n +2 is a common way to drop a header line:
tail -n +2 data.csv | sort
Follow a log live: tail -f
tail -f /var/log/nginx/error.log
tail keeps printing new lines as they’re written. Press Ctrl+C to stop. Start with more history:
tail -n 200 -f /var/log/nginx/access.log
-f vs -F
Log rotation renames the log file and creates a new one. tail -f follows the old file by its descriptor and goes quiet after rotation. tail -F follows the name: it notices the new file and reopens it.
tail -F /var/log/app/app.log
Use -F for anything that runs for a while.
Follow several logs at once
tail -F /var/log/nginx/access.log /var/log/nginx/error.log
Each block of output gets a ==> filename <== header.
Filter while following
tail -F /var/log/nginx/access.log | grep --line-buffered ' 500 '
tail -F /var/log/auth.log | grep --line-buffered 'Failed password'
--line-buffered makes grep print matches immediately instead of waiting to fill a buffer. See grep examples.
Stop when a process exits
tail -f --pid=12345 build.log
Logs in the systemd journal
Many services log to journald instead of files. The equivalent of tail -f is:
journalctl -u nginx -f
journalctl -u myapp -n 100 -f
For containers, use docker logs -f --tail 100 container. See journalctl and docker logs.
Extract a range of lines
Lines 100–120 of a file:
sed -n '100,120p' file
# or
head -n 120 file | tail -n 21
sed -n is clearer and stops reading at line 120 if you add 120q: sed -n '100,120p;120q' file.
less +F: follow with scrollback
less +F file follows the file like tail -f. Press Ctrl+C to stop following and scroll or search with /pattern. Press F to resume following. This is often nicer than tail -f when you need to look back. See less.
multitail and lnav
For heavy log work, look at:
- lnav — merges, colours and lets you query multiple logs, including compressed ones.
- multitail — several logs in split windows.
Both are in most distributions’ repositories.
Quick reference
| Task | Command |
|---|---|
| First N lines | head -n N file |
| Last N lines | tail -n N file |
| Skip first line | tail -n +2 file |
| All but last N | head -n -N file |
| Follow log | tail -F file |
| Follow and filter | tail -F f | grep --line-buffered x |
| Lines X–Y | sed -n 'X,Yp' file |
| Follow a service | journalctl -u name -f |
Related: cat and Nginx logs.