cat (short for concatenate) prints files to the terminal. Its original job is joining several files into one, but on servers it’s mostly used to look at short files, feed data into pipelines and write config files with heredocs.

cat /etc/os-release
cat /etc/hostname

For long files, cat scrolls everything past at once. Use less to page through them, and head/tail for the beginning or end. See head and tail and less.

Useful options

cat -n file        # number all lines
cat -b file        # number non-empty lines only
cat -s file        # squeeze repeated blank lines into one
cat -A file        # show hidden characters: tabs as ^I, line ends as $, CR as ^M

cat -A is a great debugging tool:

  • ^M$ at the line ends means the file has Windows (CRLF) line endings. That breaks shell scripts with errors like /bin/bash^M: bad interpreter. Fix it with dos2unix file or sed -i 's/\r$//' file.
  • ^I shows tabs where spaces were expected. That matters in YAML and Makefiles.
  • Trailing spaces show up before the $.

Concatenate files

cat part1.sql part2.sql > all.sql          # combine into a new file
cat header.html body.html footer.html > page.html
cat new-hosts.txt >> /etc/hosts            # append (needs root; see below)

> overwrites the target and >> appends. Never redirect into one of the input files: cat a b > a empties a before reading it.

Combine split archives:

cat backup.tar.gz.part-* > backup.tar.gz

Write files with a heredoc

The most common server use. Write a multi-line file without an editor:

cat > /tmp/app.env <<'EOF'
APP_ENV=production
APP_PORT=3000
EOF

Quoting 'EOF' stops the shell from expanding $variables inside. Leave the quotes off when you want expansion:

cat > hello.txt <<EOF
Deployed by $USER on $(date -I)
EOF

Writing to root-owned files

sudo cat > /etc/file doesn’t work. The redirect is done by your shell, not by sudo. Use tee:

sudo tee /etc/sysctl.d/99-custom.conf > /dev/null <<'EOF'
vm.swappiness = 10
EOF

Append with sudo tee -a. See the tee command.

Pipes and “useless use of cat”

cat access.log | grep 'POST'      # works
grep 'POST' access.log            # same, one process fewer

Most tools read files directly, so cat file | isn’t needed. It’s harmless in interactive use, and some people find cat file | … easier to edit when building pipelines step by step.

Command Use
tac file Print lines in reverse order
less file Page through large files and search them
head -n 20 file First lines
tail -f file Follow a growing log
zcat file.gz Print a gzip-compressed file (also zless, zgrep)
nl file Number lines with more formatting options
bat file cat with syntax highlighting and line numbers (separate install)

Binary files

catting a binary file can fill the terminal with garbage and even change terminal settings. If that happens, type reset and press Enter. To check what a file is first, use file name. To look inside safely, use xxd file | head or strings file.

Quick reference

Task Command
Print file cat file
Number lines cat -n file
Show tabs and line endings cat -A file
Join files cat a b > c
Append cat a >> b
Write file (heredoc) cat > f <<'EOF' … EOF
Write root-owned file sudo tee f > /dev/null <<'EOF' … EOF

Related: grep and ls.

  • Linux
  • Command Line
  • Basics