# tail — Show the End of Files and Follow Logs

> Practical guide to tail: show the last lines of a file and follow log files in real time with -f/-F, plus filtering and monitoring.

Source: https://www.jpkc.com/db/en/cheatsheets/files-text/tail/

<!-- PROSE:intro -->
tail shows you the end of a file – by default the last 10 lines. Its most famous feature is follow mode `-f`: with it you watch a log file in real time and see new entries the moment they are written. Mind the difference between `-f` (follows the open file descriptor) and `-F` (follows the filename and reopens the file after a rotation) – for rotating logs `-F` is almost always the right choice. With `-n +N` you jump to a starting line, for instance to skip the header row of a CSV. This guide walks you through follow mode, range selection and the most important pipeline patterns.
<!-- PROSE:intro:end -->

## Basic Usage

`tail <file>` — Show the last 10 lines of a file (default).

```bash
tail error.log
```

`tail -n <count> <file>` — Show the last N lines of a file.

```bash
tail -n 50 access.log
```

`tail -<count> <file>` — Shorthand for -n. Show the last N lines.

```bash
tail -20 error.log
```

`tail -n +<line> <file>` — Show all lines starting from line N (skip the first N-1 lines).

```bash
tail -n +2 data.csv
```

## Follow Mode (Real-Time Monitoring)

`tail -f <file>` — Follow a file. Output new lines as they are appended in real-time.

```bash
tail -f /var/log/syslog
```

`tail -f <file1> <file2>` — Follow multiple files simultaneously with filename headers.

```bash
tail -f /var/log/nginx/access.log /var/log/nginx/error.log
```

`tail -F <file>` — Follow with retry. Keeps following even if the file is rotated or recreated.

```bash
tail -F /var/log/app.log
```

`tail -f -n <count> <file>` — Show the last N lines and then continue following.

```bash
tail -f -n 50 /var/log/syslog
```

`tail -f -n 0 <file>` — Follow a file showing only new lines from this moment (no history).

```bash
tail -f -n 0 /var/log/app.log
```

`tail -f <file> --pid=<pid>` — Follow a file and stop when the specified process exits.

```bash
tail -f output.log --pid=$!
```

`tail -f -s <seconds> <file>` — Follow with a custom sleep interval between checks (default 1 second).

```bash
tail -f -s 0.1 /var/log/app.log
```

## Follow with Filtering

`tail -f <file> | grep '<pattern>'` — Follow a file and show only lines matching a pattern.

```bash
tail -f /var/log/syslog | grep 'ERROR'
```

`tail -f <file> | grep --line-buffered '<pattern>'` — Follow with grep using line buffering for immediate output.

```bash
tail -f access.log | grep --line-buffered '500'
```

`tail -f <file> | grep -v '<pattern>'` — Follow a file and exclude lines matching a pattern.

```bash
tail -f access.log | grep -v 'healthcheck'
```

`tail -f <file> | grep --color '<pattern>'` — Follow a file and highlight matching patterns in color.

```bash
tail -f /var/log/app.log | grep --color -E 'ERROR|WARN|$'
```

`tail -f <file> | awk '/<pattern>/ {print}'` — Follow with awk for more complex filtering and field extraction.

```bash
tail -f access.log | awk '$9 >= 500 {print}'
```

## Byte Mode

`tail -c <bytes> <file>` — Show the last N bytes of a file instead of lines.

```bash
tail -c 200 data.bin
```

`tail -c <size>K <file>` — Show the last N kilobytes. Supports K, M, G suffixes.

```bash
tail -c 1M large-file.log
```

`tail -c +<offset> <file>` — Show all bytes starting from byte N (skip first N-1 bytes).

```bash
tail -c +100 data.bin
```

## Multiple Files

`tail <file1> <file2>` — Show the last 10 lines of each file with filename headers.

```bash
tail error.log access.log
```

`tail -n <count> <file1> <file2>` — Show the last N lines of multiple files.

```bash
tail -n 5 *.log
```

`tail -q <file1> <file2>` — Quiet mode. Suppress filename headers when showing multiple files.

```bash
tail -q -n 1 *.csv
```

`tail -v <file>` — Verbose mode. Always show filename header, even for a single file.

```bash
tail -v -n 5 data.txt
```

## Pipelines

`<command> | tail` — Show only the last 10 lines of command output.

```bash
history | tail
```

`<command> | tail -n <count>` — Show only the last N lines of command output.

```bash
git log --oneline | tail -n 5
```

`<command> | tail -n 1` — Get only the last line of output.

```bash
wc -l *.py | tail -n 1
```

`sort <file> | tail -n <count>` — Show the last N items after sorting (e.g. largest values).

```bash
du -sh */ | sort -h | tail -n 5
```

## Common Patterns

`tail -n +2 <file>` — Skip the header line and show all remaining data lines.

```bash
tail -n +2 data.csv
```

`head -n <end> <file> | tail -n <count>` — Extract a specific range of lines from a file.

```bash
head -n 20 data.txt | tail -n 5
```

`tail -n +<start> <file> | head -n <count>` — Alternative range extraction: start at line N and take M lines.

```bash
tail -n +10 data.txt | head -n 5
```

`tail -f /var/log/*.log` — Monitor all log files in a directory simultaneously.

```bash
tail -f /var/log/nginx/*.log
```

`tail -f <file> | tee <output_file>` — Follow a file and save the output to another file at the same time.

```bash
tail -f app.log | tee filtered.log
```

`tail -f <file> | while read line; do echo "$(date): $line"; done` — Follow a file and prepend a timestamp to each new line.

```bash
tail -f app.log | while read line; do echo "$(date '+%H:%M:%S'): $line"; done
```

<!-- PROSE:outro -->
## Conclusion

tail is the standard tool for watching log files and the counterpart to `head`. The key everyday decision: `-f` follows the file through its descriptor and "loses" it when logrotate rotates it away; `-F` instead follows the path and reopens the new file automatically – so for production logs `-F` is usually the safe choice. When filtering in real time you often need `grep --line-buffered`, otherwise pipeline buffering holds the output back. And remember that `tail -f` never ends on its own – stop it with Ctrl-C or tie it to a process lifetime with `--pid`.

## Further Reading

- [GNU Coreutils manual: tail](https://www.gnu.org/software/coreutils/manual/html_node/tail-invocation.html) – complete reference for every option
- [man7.org: tail(1)](https://man7.org/linux/man-pages/man1/tail.1.html) – the Linux manual page
<!-- PROSE:outro:end -->

## Related Commands

- [head](https://www.jpkc.com/db/en/cheatsheets/files-text/head/) – show the first lines of files
- [less](https://www.jpkc.com/db/en/cheatsheets/files-text/less/) – page through files screen by screen (also follows with +F)
- [grep](https://www.jpkc.com/db/en/cheatsheets/files-text/grep/) – search lines by pattern

