Updated: 8 October 2026 · Applies to: Debian 13, Ubuntu 24.04 and 26.04 (GNU coreutils 9.7 and uutils 0.10.0, less 590 and 668, util-linux more 2.39 and 2.41)

To display a file in Linux, use cat for short files, less to page through long ones, head and tail to see the first or last lines, and tail -f to watch a log file while it grows:

cat notes.txt          # print the whole file
less app.log           # scroll and search (q to quit)
head -n 20 app.log     # first 20 lines
tail -n 50 app.log     # last 50 lines
tail -f app.log        # follow new lines (Ctrl+C to stop)

The examples below use a 10-line application log, app.log.

cat: print whole files

cat prints one or more files one after the other. -n numbers the lines:

$ cat a.txt b.txt
Line A
Line B
Line C
$ cat -n a.txt b.txt
     1  Line A
     2  Line B
     3  Line C

To join files into a new one, redirect the output: cat a.txt b.txt > all.txt (see redirecting command output).

cat -A makes invisible characters visible: ^M at a line end means Windows (CRLF) line endings, ^I is a tab, and $ marks the end of each line. This is the quickest way to find out why a config file edited on Windows misbehaves:

$ cat -A windows.conf
server_name example.com;^M$
root /var/www/html;^M$

tac prints a file with the last line first and nl numbers it; see cat and tac with examples.

less: page through and search large files

less app.log opens the file one screen at a time and does not load it all into the terminal, so it works on logs of any size. The most useful keys (from less --help):

  • Space or f: next screen. b: previous screen. Enter or j: one line down.
  • g: first line. G: last line.
  • /text then Enter: search forward. ?text: search backward. n and N: next and previous match.
  • &text: show only the lines that match, like a live grep. Type & and Enter with no text to show all lines again.
  • F: follow the end of the file like tail -f. Press Ctrl+C to stop following and scroll again.
  • q: quit. h: help.

Handy options: less -N shows line numbers, less -S cuts long lines instead of wrapping them (good for wide logs), and less -i makes searches ignore case unless you type a capital letter. An option that starts with + is run as a command on start, so less +G app.log opens at the end and less +F app.log starts in follow mode.

If less asks may be a binary file. See it anyway?, answer n: the file is not text. Check what it is with file (see how to find out file types):

$ file app.log windows.conf
app.log:      ASCII text
windows.conf: ASCII text, with CRLF line terminators

more: the older pager

more also shows a file one screen at a time (Space for the next screen, /text to search, q to quit), but it is simpler than less. Use it when less is not installed, which can happen in minimal containers. more +/ERROR app.log starts at the first line that contains ERROR.

head: the first lines

head prints the first 10 lines by default; -n sets another number:

$ head -n 3 app.log
2026-10-07 21:00:01 INFO  worker started (pid 4121)
2026-10-07 21:00:02 INFO  connected to database
2026-10-07 21:05:13 WARN  slow query: 2.4 s
  • head -n -8 app.log: everything except the last 8 lines (here, the first 2).
  • head -c 20 app.log: the first 20 bytes.
  • With several files, head prints a ==> app.log <== heading above each one.

tail: the last lines

$ tail -n 3 app.log
2026-10-07 21:20:00 INFO  backup job queued
2026-10-07 21:31:47 ERROR disk /var at 91%
2026-10-07 21:32:00 INFO  rotated logs

tail -n +9 app.log starts at line 9 and prints to the end. To print a range from the middle, use sed:

$ sed -n '4,6p' app.log
2026-10-07 21:10:44 INFO  cache cleared
2026-10-07 21:15:09 ERROR payment API timeout after 30 s
2026-10-07 21:15:10 INFO  retrying payment API

tail -f and tail -F: watch a log live

tail -f prints the last lines and then every new line as it is written, until you press Ctrl+C. Here a line was added from another session while tail was running:

$ tail -n 2 -f live.log
2026-10-07 21:31:47 ERROR disk /var at 91%
2026-10-07 21:32:00 INFO  rotated logs
2026-10-07 21:40:05 INFO  new request

Log files are rotated: the current file is renamed (for example to app.log.1) and a new one is created. tail -f keeps reading the old, renamed file, so new lines stop appearing. tail -F follows the file name instead and switches to the new file. When we rotated the log during a test on Debian 13, tail -f showed nothing more, while tail -F printed:

$ tail -n 1 -F rot.log
2026-10-07 21:32:00 INFO  rotated logs
tail: 'rot.log' has been replaced;  following new file
2026-10-08 00:00:01 INFO  after rotation
2026-10-08 00:00:02 INFO  second line

To watch only errors, pipe it into grep; --line-buffered makes each match appear at once:

tail -F app.log | grep --line-buffered ERROR

Compressed logs and the systemd journal

Older rotated logs are often gzipped (app.log.2.gz). Read them without unpacking: zcat prints, zless pages and zgrep searches:

$ zgrep ERROR old.log.gz
2026-10-07 21:15:09 ERROR payment API timeout after 30 s
2026-10-07 21:31:47 ERROR disk /var at 91%

Many services log to the systemd journal instead of a text file. Read those with journalctl, for example journalctl -u nginx -f (see journalctl examples). For where each service writes its logs, see common log file locations.

Common mistakes

  • Using cat on a huge log. It floods the terminal. Use less, or tail -n 100.
  • Printing a binary file. cat on a binary can leave the terminal showing strange characters. Type reset and press Enter to fix it.
  • A missing last line break. If the last line of a file has no newline character, the shell prompt appears on the same line, right after the text. The file is fine; cat -A shows no $ at the end of that line.
  • Using tail -f on logs that rotate. Use tail -F, as shown above.
  • Writing cat file | grep text. It works, but grep text file reads the file itself; see grep, sort, uniq, wc, cut and tr.

Ubuntu 26.04 note

On Ubuntu 26.04, cat, head, tail, tac and nl come from uutils coreutils 0.10.0 (the Rust version). Every example above gave the same output as GNU coreutils 9.7 on Debian 13, except the messages of tail -F during a rotation: uutils printed tail: 'rot.log' has become inaccessible: No such file or directory and then tail: 'rot.log' has appeared; following new file. less and more are separate packages and are the same on both.

Related: list files with ls and match file names with wildcards.

Ucartz services for this topic

Was this answer helpful? 0 Users Found This Useful (0 Votes)