cat and more commands in Linux: Read, Join and Page Files

LinuxForDevices featured banner: Read Files Without the Scramble

cat prints a file to your screen and stops there. The name is short for concatenate, because joining files is the job it was written for and reading a long one was never part of the plan.

The cat command in Linux hands every byte of a file to standard output, so a long log scrolls past faster than you can read it and a file that is not text can leave the terminal unreadable until you type a recovery command blind. Both problems come from that one design choice.

What cat does with a file

cat copies each file you name, in the order you name them, to standard output, and it does no interpretation on the way. Nothing is added, reordered, or held back.

The confusion around cat comes from a short list of behaviours, and each one is a consequence of that contract.

  • It adds no separator between files, so their contents arrive as one run of lines.
  • It never pauses, so a file longer than the screen is gone before you have read it.
  • It interprets nothing, so control bytes reach the terminal as instructions.

The dash operand belongs to the same contract, and the coreutils manual gives the example cat f – g, which prints f, then whatever standard input holds, then g, as one stream. A dash where a filename would go means standard input rather than a file on disk.

What you need before the first command

Both commands are already present on any mainstream Linux system. cat is part of GNU coreutils and more comes from util-linux, so neither one needs an install step.

Versions matter for the option list, and both commands will tell you which build you have.

cat --version | head -1
cat (GNU coreutils) 9.4
more --version 2>&1 | head -1
more from util-linux 2.39.3

The option set matches the current GNU coreutils manual, and the commands on this page ran on the build above.

Reading files with the cat options that carry weight

A handful of options covers almost everything you would want from cat, and each one changes a single thing about the output. The table is the reference for the rest of this section.

OptionWhat it changesWhere it helps
-Ashows non-printing characters, tabs, and line endings togetherspotting a stray tab in a configuration file
-bnumbers the lines that hold textreading a file with empty lines in it
-nnumbers every linereferring to a line by number afterwards
-ssqueezes a run of blank lines into onelogs and pasted output
-Tshows each tab as caret Ichecking indentation
-Eputs a dollar sign at the end of each lineconfirming a file ends with a newline
-vshows non-printing characters except tabs and line endspeeking at a file that is not text
ends the option listreading a file whose name starts with a dash

Print one file

Give cat a filename and the contents land on the screen with nothing added to them. I used two short files, notes.txt and servers.txt, so that the output stays on one screen.

cat printing the contents of notes.txt
cat prints the file and hands the prompt back

The prompt returns when the file ends, and the exit status stays 0 unless something went wrong.

Name a file that does not exist and the other operands still print, because cat reports the failure and carries on to the end of the list. The exit status is where that failure shows up.

cat reporting a missing operand and the exit status 1
A missing operand, the diagnostic it prints, and the exit status

Print several files in one output

Naming several files joins them into one stream, and nothing marks the join. The output below is the whole of both files, printed in the order I named them.

cat printing two files as one output stream
Both files print in the order they were named, joined with no separator

Argument order is output order, so naming the server list first prints the server list first. When a boundary between files matters, the pager puts a filename header above each file instead.

Number the lines

The -n option numbers every line including the blank ones, while -b numbers only the lines that hold text.

cat -n numbering every line of two files
The -n option numbers every line in the output

The numbers exist in the output and never in the file, so this is a reading aid rather than an edit.

Reveal tabs and line endings

A tab and a space look alike in the default terminal font, which is how a tab-separated file ends up misaligned in one viewer and tidy in another. The -A option makes the tab and the end of each line visible at the same time.

cat -A showing each tab as caret I and each line end as a dollar sign
Tabs and line endings become visible with -A

Each tab prints as caret I and each line closes with a dollar sign, so a missing final newline stops being invisible.

Squeeze the blank lines

Runs of blank lines pile up in log files and in anything pasted from another tool. I made a file with a block of empty lines between two letters to watch the option work, and the -s option turned that block into a single blank line.

cat -s blanks.txt
a

b

Run the same file without the option and a block of empty lines sits between the two letters, which is the state -s is there to remove.

Put the lines back in order

tac reverses the line order of a file, and the name is cat read backwards.

tac printing a changelog file in reverse line order
tac reverses the line order of the file

The reversal works on lines rather than characters, so the last line of the file becomes the first line of the output.

Writing, appending and copying files with cat

With no file operand cat reads standard input, which turns the same command into a writer. The redirect you add decides whether the output lands on the screen or in a file.

Create a file from the keyboard

Redirect the output to a name that does not exist yet and cat waits for you to type. Nothing prints, no prompt comes back, and the cursor sits on a blank line until you press Ctrl+D to signal the end of input.

cat waiting for keyboard input after output was redirected to a file
The redirect leaves the cursor waiting for your input

I typed the lines shown above into environment.txt, then printed the file back to confirm they had landed.

Write a file in one command with a heredoc

A heredoc keeps the content inside the command, so the same command still works when you run it again from your shell history or from a script. Quoting the marker stops the shell from expanding anything between the two markers.

cat > probe.txt <<'EOF'
probe: 8080
EOF

The two marker lines belong to the shell, and everything between them is written into probe.txt as a single file.

Append instead of replace

A single redirect replaces the contents of the target, and a doubled one adds to the end instead. The changelog keeps its own lines here and the notes land underneath them, which is the difference the second redirect makes.

cat changelog.txt > copy/appended.txt
cat notes.txt >> copy/appended.txt
cat copy/appended.txt
deploy release to staging
then promote to production
nginx: 2 workers
postgres: 1 primary
redis: 1 cache

Copy and merge with a redirect

A redirect turns cat into a copy command, and several files ahead of the redirect turn it into a merge.

cat notes.txt > copy/copied.txt
cat notes.txt servers.txt > copy/inventory.txt
wc -l copy/inventory.txt
5 copy/inventory.txt

The count comes back at 5 lines, which is the three from notes.txt plus the two from servers.txt. wc counts them, and a line count is the fastest check that a merge did what you expected.

The redirect that empties its own source

Put the same name on both sides of the redirect and the file is gone, because the shell opens the destination and truncates it before cat reads a byte. The Bash manual gives that as a rule, with no warning attached to it.

wc -c reporting zero bytes after cat truncated the file it was reading
The same name on both sides of the redirect leaves an empty file

I ran that command against a file of 52 bytes and the size came back as nothing, with no error and no message to warn me.

Reading a long file with more

more prints one screenful and holds the rest, which is the behaviour cat cannot give you. The prompt at the bottom of the screen is the signal that the file continues.

When to switch from cat to a pager

more holding the first screenful of an access log with a percentage prompt
more stops at the first screenful and waits for a key

That access log holds 62 lines, and more stopped at the first screenful with a prompt reading 30 percent, so the rest of the file stayed behind the pause. The screen stays put until you press a key, which is the behaviour cat does not have.

The navigation keys

These keys are the ones worth knowing before you open a file you cannot read to the end.

KeyWhat it does
spaceshows the next screenful
entermoves down one line
dmoves down half a screenful
bgoes back one screenful
/textsearches forward for the first matching line
=prints the current line number
:nopens the next file when you named several
:pgoes back to the previous file
qquits and returns you to the prompt
hshows the full key list

Start at a line or at a search hit

The operand forms below skip ahead instead of pressing space, and each one takes a plus sign followed by what you are looking for. A number starts the display at that line, and a slash starts it at the first line that matches, so an error near the bottom of a log is one command away instead of a page of keypresses.

more jumping to the first line matching a search string
The plus slash operand lands on the first matching line

The skip is announced on screen, and the matching line sits near the top with the rest of the file behind the same prompt.

more against less

The man page for more is direct about the comparison. It calls itself a filter for paging through text one screenful at a time, then notes that less provides more emulation plus extensive enhancements.

Reach for less when you need to move backwards through a file line by line or search in both directions, and stay with more when a forward read is all the job needs.

When cat fills the terminal with garbage

Printing a file that is not text is the one cat mistake that costs more than a scroll, because those bytes reach the terminal and the terminal acts on them.

What the terminal does with those bytes

cat performs no interpretation of its own, so control bytes arrive as instructions rather than as text. An answer on Unix Stack Exchange puts the cause in the right place, describing the terminal as sitting in a state you forced it into by sending it control characters.

cat with the -v option is the safe way to look at a file you are unsure about, since the control characters come back in caret notation instead of being handed to the terminal.

I ran it against the first bytes of an executable, and the escape byte came back as a visible caret question mark.

head -c 24 /bin/ls | cat -v
^?ELF^B^A^A^@^@^@^@^@^@^@^@^@^C^@M-7^@^A^@^@^@

Identify a file before you print it

The file command reports what a file is, and one line of report is cheaper than a terminal recovery. I pointed it at the log and the tab-separated file from earlier, and both came back as text, which is the answer that lets you print them without a second thought.

file logs/access.log staff.tsv
logs/access.log: ASCII text
staff.tsv:       ASCII text

Recover a terminal that has stopped making sense

The recovery comes down to a pair of commands, and the harder problem is typing them while the screen is unreadable. The accepted answer on that thread warns about this directly, since the keystrokes go in blind.

reset
stty sane
What happenedWhat the terminal is doingWhat to run
a binary file was printedcontrol bytes were read as instructionsreset
a device file was printedthe same, with a stream that never endsCtrl+C, then reset
stray characters survive a clearthe line settings changed and clear does not undo themstty sane

cat in a pipe, and when it is not useless

I ran both forms against the same log and the counts agreed. The usual complaint about cat in a pipe is the extra process, since a filter like grep reads a file on its own.

cat logs/access.log | grep -c 500
2
grep -c 500 logs/access.log
2

Both forms return the same count, which is the test the practice is judged by, and grep covers the other side of that pipe.

Joining is where cat in a pipe does work no other command can do, because the stream arrives from several files at once.

cat logs/access.log servers.txt | grep -c "500\|web"
4

When the input is one file, the pipe is decoration, and when the input is several files, the pipe is the command. For a slice of a file rather than all of it, the head command and the tail command take the line count instead.

Point cat at output and more at reading

The command names carry the split. cat concatenates and writes, which is why it takes files, pipes, and redirects so well and why it has no way to hold a screen still.

Reach for more as soon as a file runs past the screen, and start from the line you need instead of the top of the file.

cat --help | more
more +/ERROR /var/log/syslog

The first command pairs the two on a long help page, and the second opens a log at the first error line with the rest still behind the prompt. For a file you plan to change rather than read, editing it in the terminal is the next step after reading it.

Frequently asked questions about cat and more

Every answer below is the short version of a section above.

What does cat stand for in Linux?

The name is short for concatenate, which describes what the command does with several files. It chains them together into one output stream.

What does the cat command do?

cat copies each file you name to standard output, and it reads standard input when you name no file at all. Printing, joining, creating, and copying files all come from that one behaviour.

How do I come out of the cat command?

Press Ctrl+D to end the input when cat is waiting for you to type, and press Ctrl+C to stop it when it is printing a file you no longer want to read.

What is the difference between cat and more?

cat prints everything at once and returns the prompt, while more prints one screenful and waits for a key before it continues. Use cat when the output is short or goes into a file, and more when the file is longer than the screen.

Can cat read a binary file?

cat will copy the bytes wherever you point it, including into another file. Printing those bytes in a terminal is what causes trouble, because the terminal reads some of them as control sequences, so use file or xxd when the content is not text.