bat: A cat Clone with Syntax Highlighting

bat: A cat Clone with Syntax Highlighting

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

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: I just learned the name and now bat doesn't work — that's sad...
Linny-senpai: Don't worry. 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 -s "$(which batcat)" ~/.local/bin/bat

If ~/.local/bin isn't on your PATH, append it in ~/.bashrc and reload.

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

Confirm the install and version:

$ bat --version
bat 0.24.0

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.
$ 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 exactly 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 (the default)
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 variable. Add this line to ~/.bashrc.

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

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.

Exercise 1: Open a config file (e.g. ~/.bashrc) with bat and confirm it shows line numbers and color.

Exercise 2: Open the same file with bat -pp and confirm the decorations and pager are gone, matching cat.

Exercise 3: Run bat -r 1:10 ~/.bashrc and confirm only the first 10 lines are shown.

Hint for Exercise 1
bat ~/.bashrc

Success if you see line numbers on the left, a file-name header on top, and shell-script syntax highlighting.

Hint for Exercise 2
bat -pp ~/.bashrc

The 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).

Hint for Exercise 3
bat -r 1:10 ~/.bashrc

The format is start:end. Also try bat -r 5: file (from line 5) and bat -r :5 file (first 5 lines) to get a feel for ranges.

Next Reading