less

Read a file a screen at a time, and search it

Updated 2026-08-28

less shows a file a screen at a time and lets you move around inside it. It is Debian's default pager, so man, systemctl and journalctl all hand their output to it. The shared inheritance is why they all quit on q, and why several of them grew a --no-pager flag.

The keys are what no example can show. All of these are listed by less --help, and h prints the same list without leaving the file.

Key What it does
q quit
SPACE, b forward, back one screen
g, G first line, last line
/text, ?text search forward, search backward
n, N next match, previous match
&text show only the lines that match
F keep reading as the file grows, like tail -f; Ctrl-C stops
v open the file in $VISUAL or $EDITOR
-N then Enter turn line numbers on or off without restarting

Searching is case-sensitive. -i makes it ignore case for any pattern with no capital letter in it, and -I ignores case whatever the pattern looks like.

The behaviour that catches people out is on the other side. less pages only while it is talking to a terminal. Send it into a pipe or a file and it copies its input straight through, ignoring every display flag you gave it, so less -N report.txt > numbered.txt writes a file with no numbers in it.

Sample files used on this page

Every example below was run against these files. Recreate them to follow along.

report.txt forty numbered lines, the same file the wc and head pages count

line 1 of the report
line 2 of the report
line 3 of the report

line 40 of the report

access.log ten requests in combined log format, as the second file for the examples that open two

203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231
198.51.100.7 - - [13/Aug/2026:09:14:22] "GET /index.html HTTP/1.1" 200 512
198.51.100.7 - - [13/Aug/2026:09:14:25] "GET /missing.html HTTP/1.1" 404 162
203.0.113.5 - - [13/Aug/2026:09:15:47] "GET /index.html HTTP/1.1" 200 512
192.0.2.44 - - [13/Aug/2026:09:16:03] "POST /login HTTP/1.1" 302 0
192.0.2.44 - - [13/Aug/2026:09:16:04] "GET /dashboard HTTP/1.1" 200 4021
198.51.100.7 - - [13/Aug/2026:09:18:51] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:19:10] "GET /api/status HTTP/1.1" 500 89
192.0.2.44 - - [13/Aug/2026:09:20:33] "GET /dashboard HTTP/1.1" 200 4021
15 outputs, collapsed by default

Opening a file

less report.txt and then q. Everything here needs a terminal to do anything at all, which is why none of it carries output: these flags change the screen less draws, and a replay has no screen.

Page through a file

less report.txt

Forty lines, one screen at a time, q to leave. Nothing is loaded up front. A log far larger than memory opens straight away, where cat would spend both the time and the memory.

Number the lines while reading

less -N report.txt

-N (--LINE-NUMBERS) puts a line number in the left margin. Typing -N at the : prompt toggles it without restarting, which is true of most of these flags.

Stop long lines wrapping

less -S access.log

-S (--chop-long-lines) truncates each line at the right edge instead of folding it onto the next row, so one log entry stays on one line. The arrow keys scroll sideways to read the rest.

Start at the end of the file

less +G access.log

Anything after + is a command run as the file opens, and G is the key for the last line. On a log, where the newest entry is the one you came for, that is how to open it.

Start at the first match instead

less +/500 access.log

+/pattern searches as it opens and stops on the first hit, with n for the next. Add -p in place of +/ for the same thing spelled as an option.

Follow a file as it grows

less +F /var/log/syslog

+F behaves like tail -f, printing new lines as they arrive. Ctrl-C drops back into the file where you can search and scroll, and F starts following again. tail cannot drop out of following like that.

Keep the text on screen after quitting

less -X report.txt

-X (--no-init) stops less restoring the screen on exit, so what you were reading is still in the scrollback. -F (--quit-if-one-screen) pairs with it: a file that fits on one screen is printed and less exits without waiting for q.

Keep the colours

ls --color=always -l | less -R

-R (--RAW-CONTROL-CHARS) passes ANSI colour codes through to the terminal instead of showing them as ESC[0m. Without it, any coloured output paged through less is unreadable.

less only pages when it is talking to a terminal

Give less anywhere to write other than a terminal and it stops being a pager. It copies its input to its output and exits, which is exactly what cat does.

A piped less is a cat

less report.txt | head -3

No pager, no prompt, no waiting for q. The bytes go straight down the pipe.

Show output
line 1 of the report
line 2 of the report
line 3 of the report

The display flags are dropped in silence

less -N report.txt | head -3

-N asked for line numbers and there are none. Nothing warns you, so less -N report.txt > numbered.txt writes a file identical to the input.

Show output
line 1 of the report
line 2 of the report
line 3 of the report

The options are still parsed, though

LESS=--nosuchflag less report.txt | head -2

less reads its default options from $LESS before anything else, and complains here about one that does not exist. The complaint proves the variable was read; the file is then copied through regardless.

Show output
There is no nosuchflag option ("less --help" for help)
line 1 of the report
line 2 of the report

Several files are simply joined

less report.txt access.log | sed -n '39,42p'

Interactively these are two files with :n and :p to move between them. Down a pipe they are one stream, and the join between them is invisible.

Show output
line 39 of the report
line 40 of the report
203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231

more is not the same

more report.txt | head -4

more prints a header naming each file even when nothing is watching, so it cannot be dropped into a pipeline the way less can. The joke that "less is more" is about the keys and the backward scrolling.

Show output
::::::::::::::
report.txt
::::::::::::::
line 1 of the report

Files less will not just show you

A file that is not there

less missing.txt

The complaint goes to standard error and no pager is started. less names the file without the less: prefix most commands put in front of an error.

Show output
missing.txt: No such file or directory

A directory

less /etc

less reads files. Use ls for what is in a directory.

Show output
/etc is a directory

Forcing it to open one anyway

gzip -n -c access.log > access.log.gz && less -f /etc | head -2

-f (--force) tells less to open anything, including a directory or a device. What comes back from a directory is not text and reads as an error.

Show output
read error

A binary file gets a question first

gzip -n -c access.log > access.log.gz && less access.log.gz | head -2

The prompt waits for y at a terminal. With nothing to answer it, less stops and prints nothing else. -f skips the question; lesspipe answers it properly.

Show output
"access.log.gz" may be a binary file.  See it anyway?

Compressed files, and the hook that makes them readable

Debian ships a filter called lesspipe that less can run over a file before showing it. It handles gzip, tar, deb, PDF and a dozen other formats. It is off until you switch it on.

The direct answer for a gzipped file

gzip -n -c access.log > access.log.gz && zless access.log.gz | head -2

zless decompresses and pages in one step. A zcat, a zgrep and a zdiff sit beside it, all from the same package as gzip.

Show output
203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231

Or teach less to do it for every format at once

gzip -n -c access.log > access.log.gz && eval "$(lesspipe)" && less access.log.gz | head -2

lesspipe prints the two export lines that set $LESSOPEN and $LESSCLOSE. eval runs them. From then on less on a .gz, a .tar or a .deb shows you what is inside it.

Show output
203.0.113.5 - - [13/Aug/2026:09:12:01] "GET /index.html HTTP/1.1" 200 512
203.0.113.5 - - [13/Aug/2026:09:12:03] "GET /style.css HTTP/1.1" 200 231

Debian writes the hook for you and leaves it off

grep lesspipe ~/.bashrc

The line is in the .bashrc every new account starts from, commented out. Uncommenting it is the whole of the setup. It also explains why less on an archive behaves differently on two machines that look identical.

Show output
# make less more friendly for non-text input files, see lesspipe(1)
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

Everything else that hands you to less

man pages are paged, unless nobody is watching

man ls | head -1

man runs its output through a pager. That pager makes the same terminal check less does, so piped you get the formatted page and no prompt.

Show output
LS(1)                            User Commands                            LS(1)

Choose the pager yourself

PAGER=cat man ls | head -1

$PAGER is the general setting and $MANPAGER overrides it for man alone. man --pager=cat does the same thing for one invocation.

Show output
LS(1)                            User Commands                            LS(1)

Check what a key does without leaving the shell

less --help | col -b | grep -E "Forward forever|Display only matching" | tr -s " \t" " "

less --help is the same list h shows from inside. It arrives with backspace overstrike for the bold, which is what col -b removes; tr then collapses the column padding.

Show output
 F Forward forever; like "tail -f".
 &pattern * Display only matching lines.