bat: A cat Clone with Syntax Highlighting

bat: A cat Clone with Syntax Highlighting

What you'll be able to do

  • Display files with color and line numbers using `bat`
  • Fix the Ubuntu `batcat` naming issue yourself
  • Strip decorations with `-p` and `-pp` to match `cat` output

Prerequisites (read these first)

What You'll Learn

  • How to use bat instead of cat to display files with color and line numbers
  • How to fix the Ubuntu/Debian batcat issue (the command isn't named bat)
  • How to strip decorations to match cat's output for pipes and scripts
  • Practical extras like coloring man pages that pay off daily

Target Audience: Linux beginners, anyone underwhelmed by cat's plain output

Words used here (sorted out first)

  • Syntax highlighting: coloring text by its grammar. "Color-coding the syntax" means the same thing.
  • Pager: a tool that shows a long file one screen at a time. less is the classic one.
  • Standard output: where a command's result goes. Normally that is your screen.
  • Pipe: the | symbol. It hands the left command's result to the right command.
  • Symlink: a shortcut that points at the same thing under another name.
  • PATH: the list of places the shellAn interactive program that reads the commands you type and runs them. searches for commands. A command outside those places cannot be called by name alone.

Introduction: Lina's "cat Is Hard to Read" Problem

Lina: Linny-senpai, I opened a config file with cat config.json, but everything's the same color and my eyes just slide right off it. Reopening it in an editor is a hassle, too.
Linny-senpai: Ah, cat just "dumps the contents as-is" — no color, no line numbers. There's an upgraded cat called bat that makes it readable in one shot.
Lina: bat? Like the animal?
Linny-senpai: Spelled b-a-t, yeah. It's a play on cat. Syntax highlighting, line numbers, even Git diff markers — all built in from the start. Let's learn it together today.

The Short Answer

  • bat = a cat replacement with color, line numbers, Git diffs, and automatic paging out of the box
  • On Ubuntu/Debian, sudo apt install bat installs it but the command is batcat (aliasing it to bat is standard)
  • For pipes and scripts, bat -p (no decorations) / bat -pp (no pager either) bring you back to cat-like behavior

1. What Is bat?

Conclusion: bat is a cat replacement. It displays file contents just like cat, but adds syntax highlighting, line numbers, Git change markers, and automatic paging.

Lina: What's actually different between bat and cat?
Linny-senpai: They do the same job — "show a file's contents." The difference is readability. Where cat streams plain black-and-white text, bat color-codes the syntax, adds line numbers, and even marks changed lines when you're in a Git repo.
Lina: So thorough. Can it actually replace cat?
Linny-senpai: For the everyday "let me peek at this file," bat covers almost all of it. It isn't a perfect drop-in replacement, though, so you need a little care in pipes and scripts. We'll cover that later.

bat is a Rust tool developed by sharkdp/bat. The main differences from cat:

Aspect cat bat
Syntax highlighting None Yes (auto-detects the language)
Line numbers With -n On by default
Git diff display None Yes (marks changed lines)
Long files Scroll past all Auto-launches less (a pager)
Non-printable chars -A symbolizes -A symbolizes
Behavior in a pipe Always plain text Auto-disables decorations (later)

2. Install and the batcat Issue

Conclusion: On Ubuntu/Debian, apt install bat works, but the command is named batcat to avoid a name clash. Symlinking it to bat is the standard fix.

Lina: I want to install it right now! How?
Linny-senpai: The package name differs slightly per distribution. Let's start here.
# Ubuntu / Debian family
$ sudo apt install bat

# Fedora / RHEL family
$ sudo dnf install bat

# Arch Linux
$ sudo pacman -S bat

# macOS (Homebrew)
$ brew install bat

The Ubuntu/Debian Trap: the Command Is batcat

On Debian, to avoid a binary name clash with another package, the command is named batcat instead of bat. Typing bat gives you command not found.

Lina: Senpai, sudo apt install bat succeeded. But bat config.json says bat: command not found. Did the install fail?
Linny-senpai: It didn't fail. It's installed. The command is just named batcat. Try batcat --version.
Lina: Oh, it runs! So it was there all along, only under a different name.
Linny-senpai: Right. Almost everyone trips here once. It's the same pattern as the fdfind issue with fd. Add a symlink and you can call it as bat.

To use it under the name bat, create a symlink in ~/.local/bin.

mkdir -p ~/.local/bin
ln -sf "$(which batcat)" ~/.local/bin/bat

-f is there so the command still works when a link of that name already exists.

First check whether ~/.local/bin is on your PATH.

$ echo $PATH

If /home/username/.local/bin appears in the output, you can skip the next step. Only continue when it is missing.

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Don't mix up >> and >

  • >> appends to the end. What was already there stays
  • > wipes the file and rewrites it. Using > here erases everything in ~/.bashrc
  • Erased content cannot be recovered. Nothing goes to a trash folderA container that organizes files. Same idea as a "folder" on Windows or macOS.
  • This edits a real settings file on your machine. bat does not run in this site's virtual terminal, so run it in your own terminal
  • Take a copy before you run it
$ cp ~/.bashrc ~/.bashrc.bak
  • If you typed > by mistake, restore it with cp ~/.bashrc.bak ~/.bashrc

What source does

~/.bashrc is read "when you open a new terminal." Appending to it does not affect the terminal you already have open. source ~/.bashrc says "re-read it right now." Opening a new terminal has the same effect.

Confirm the install and version:

$ bat --version
bat 0.24.0

The number varies by system. Any version string means the install worked.

If You Skip the Symlink on Ubuntu

If the symlink feels like a hassle, you can read every bat in this article's examples as batcat and it still works. But the symlink lets you copy-paste bat from other articles and docs as-is, which is more convenient.

3. The Basics of Using bat

Conclusion: bat FILENAME shows the contents with color and line numbers. Pass multiple files and it separates them with labeled headers.

Linny-senpai: Usage is identical to cat — just pass the filename you want to display. Let's make a file to try the coloring on.
$ mkdir -p ~/bat-practice
$ cd ~/bat-practice
$ printf '{\n  "name": "penguin",\n  "version": "1.0.0",\n  "debug": false\n}\n' > config.json
$ bat config.json
───────┬────────────────────────────────────────
       │ File: config.json
───────┼────────────────────────────────────────
   1   │ {
   2   │   "name": "penguin",
   3   │   "version": "1.0.0",
   4   │   "debug": false
   5   │ }
───────┴────────────────────────────────────────

How to Read It

  • The numbers on the left: line numbers (the cat -n equivalent, on by default)
  • The top File: config.json: the header with the file name
  • The colors: the language is auto-detected from the extension and syntax-highlighted (JSON above)

Pass multiple files and each gets its own header as a separator.

$ bat a.txt b.txt
Lina: With cat a.txt b.txt the contents ran together and I couldn't tell where b.txt started.
Linny-senpai: Right, that's a quietly useful point. bat inserts a header per file, so checking multiple files gets much easier.

Long Files Become a Pager Automatically

Open a file too long for the screen with bat and it automatically launches less (a pager). Scroll with the arrow keys or Space, and quit with q. You won't lose your place to a cat-style flood scrolling off the screen.

4. How Do I Make It Plain Like cat?

Conclusion: To strip decorations (line numbers, header, grid lines), use -p (--plain). To also stop the pager and behave almost like cat, use -pp.

Lina: The color and line numbers are nice, but sometimes the grid lines and numbers get in the way when I just want to copy the contents.
Linny-senpai: Good observation. For that, there are options to drop the decorations — two levels of them, depending on what you need.
# Strip line numbers, header, and grid (keep color)
$ bat -p config.json

# Strip decorations AND the pager (almost identical to cat)
$ bat -pp config.json

Two Levels of Stripping Decorations

Option What's removed What stays
-p Line numbers, header, grid Color, automatic paging
-pp All of the above + automatic paging Color (on a terminal)
Lina: So -p twice is -pp. Easy to remember.
Linny-senpai: Exactly. -pp means "no decorations, no pager," so it's an easy drop-in for cat. It's the go-to when you just want a quick look at the contents.

To inspect non-printable characters (tabs, line endings, trailing spaces), use -A (--show-all).

$ bat -A messy.txt

-A visualizes tabs as ├──▶ and newlines as a -like symbol. It's great for "invisible whitespace breaks my script" troubleshooting. Same purpose as cat -A, but the color makes it clearer.

5. How Do I Customize the Display?

Conclusion: Choose which parts to show with --style (numbers / header / grid / changes, etc.), and change the colors with --theme. List available themes with --list-themes.

Lina: Can I pick finely, like "I want line numbers but not the grid"?
Linny-senpai: You can. With --style you specify the components to show, comma-separated.
# Line numbers only (no grid, no header)
$ bat --style=numbers config.json

# Line numbers and Git change markers only
$ bat --style=numbers,changes config.json

# Strip all decorations (same as -p)
$ bat --style=plain config.json

Main Components for --style

Value Meaning
numbers Line numbers
header File name header
grid Separator grid lines
changes Git change markers
full Everything
plain Nothing (equivalent to -p)

Change the color theme with --theme. List the available themes with --list-themes.

# See the list of themes
$ bat --list-themes

# Display with a chosen theme
$ bat --theme=ansi config.json

Make Settings Permanent

If typing options every time is a chore, write defaults into a config file. Generate a template with bat --generate-config-file, set your default --theme and --style there, and from then on a bare bat applies those settings.

6. How Do I View or Highlight Specific Lines?

Conclusion: Specify a line range with -r (--line-range) as start:end. Make a specific line stand out with -H (--highlight-line). Force a language with -l (--language).

Lina: For a log with thousands of lines, how do I see just a specific range?
Linny-senpai: You can specify a line range with -r. No need for tail or sedbat alone slices it out.
# Show lines 100 through 120
$ bat -r 100:120 app.log

# From line 50 to the end
$ bat -r 50: app.log

# From the start through line 30
$ bat -r :30 app.log

To make a specific line stand out with color, use -H.

# Display the whole file while highlighting line 42
$ bat -H 42 app.log

When the language isn't auto-detected (for files without an extension, say), specify it with -l.

# Highlight an extensionless file as JSON
$ bat -l json mydata
Lina: So the reason an extensionless file got no color was that the language couldn't be determined.
Linny-senpai: Right. bat guesses the language from the extension and contents, but it can miss. When it does, -l tells it "this is JSON." See the supported languages with bat --list-languages.

7. What to Watch for in Pipes and Scripts?

Conclusion: When the output goes to a pipe or a file, bat automatically strips decorations and emits plain text. Even so, it's not a perfect cat replacement, so prefer cat in scripts.

Lina: I ran bat config.json | grep debug and it worked normally. The color codes didn't get mixed in.
Linny-senpai: Nice catch. bat checks whether the output is a terminal (the screen), and when you pipe or redirect to a file, it auto-disables decorations and color. So passing it to grep or wc doesn't break anything.
# Piping yields plain text automatically
$ bat config.json | grep debug

# Redirecting to a file inserts no color codes
$ bat config.json > copy.json

Use cat in Scripts

bat is handy, but it isn't installed everywhere. If a shell script assumes bat, it breaks on a machine that lacks it. In scripts you distribute or share, use plain cat for processing that doesn't need decoration. Treat bat strictly as a tool for "when a human is looking."

Lina: What about alias cat=bat to replace cat entirely?
Linny-senpai: I get the urge, but I don't recommend it. Scripts and other people's runbooks may rely on cat's plain behavior, so overriding it with an alias can cause surprises. If anything, add it under a separate name, like alias bat='batcat'.

8. What Are the Practical Extras?

Conclusion: bat can also colorize man pages and power previews in tools like fzf. Anywhere you want "show contents in color," you can drop it in.

Linny-senpai: Since we're here, let me show a couple of uses beyond running bat on its own. Quietly effective once set up.

To colorize man pages with bat, set the MANPAGER environment variableA named value that the shell or a program can look up while running.. Add this line at the end of ~/.bashrc, then re-read it with source ~/.bashrc.

export MANPAGER="sh -c 'col -bx | bat -l man -p'"

On Ubuntu / Debian without the symlink, rewrite the bat above as batcat. Forget that and man shows nothing when you open it. The same applies to the fzf example below.

How to Read It

  • col -bx: cleans up control characters in man output (like overstrike-based bold)
  • bat -l man -p: colorizes it using the man language rules and displays it plainly (-p)
  • After setting it, opening man ls and the like color-codes headings and options for easier reading

Used as a preview in fzf (a fuzzy finder), it shows candidate file contents in color.

# Pick a file while previewing its contents in color
$ fzf --preview 'bat --color=always {}'
Lina: Why add --color=always?
Linny-senpai: The fzf preview pane can be judged as "not a terminal," and left alone, bat would strip the color. So you explicitly say "always colorize." Conversely, in normal pipes you don't add it — that's the trade-off to learn.

9. Mini Exercises: Try It on Your Box

Conclusion: Three drills — display, strip decorations, and a line range — to lock in bat's basics.

Linny-senpai: To make it stick, run these on your own system.

These exercises only read ~/.bashrc. Nothing gets written, so you can relax.

Exercise 1: Open ~/.bashrc with bat and confirm it shows line numbers and color.

Show Hint 1 (Direction)

Usage is the same as cat. Just pass the file name; no options needed.

Show Hint 2 (Command name)

Run bat ~/.bashrc. On Ubuntu without the symlink, read that as batcat.

Show Answer
$ bat ~/.bashrc

You get line numbers on the left and a file-name header on top. Shell-script syntax highlighting means it worked. If the file is long, the pager opens; quit with q.

Exercise 2: Open the same file so the decorations and pager are gone, matching cat.

Show Hint 1 (Direction)

Repeat the decoration-stripping option twice. Once still leaves color and the pager.

Show Hint 2 (Command name)

Run bat -pp ~/.bashrc.

Show Answer
$ bat -pp ~/.bashrc

Line numbers, header, and grid disappear. The pager doesn't launch and it prints all at once — nearly identical to cat ~/.bashrc (only the color remains on a terminal).

Exercise 3: Show only the first 10 lines of ~/.bashrc.

Show Hint 1 (Direction)

There is an option for a line range. You write it as start:end.

Show Hint 2 (Command name)

Use bat -r. Starting from the top, you may omit the start.

Show Answer
$ bat -r 1:10 ~/.bashrc

bat -r :10 ~/.bashrc gives the same result. Try bat -r 5: ~/.bashrc (from line 5) too, to get a feel for ranges.

Looking Back

Conclusion: bat for looking at files, cat for handing them to something else.

Lina: Let me sum up. Read with bat, add -pp when I want to copy, use -r to narrow the range.
Linny-senpai: Good summary. One more: inside scripts, use cat. Remember bat as the tool for "when a human is looking" and you won't get stuck.
Lina: And command not found on Ubuntu won't scare me now. The command is just called batcat.

Three-Line Recap

Conclusion: bat is the readable stand-in for cat, and -pp strips it back down.

  1. bat FILENAME shows a file with color and line numbers
  2. If Ubuntu says bat: command not found, the command is simply named batcat
  3. Add -pp for pipes and copying. In scripts, stick with plain cat

Next Reading

Share this article

Next steps