bat Command Reference Guide

A cat clone with syntax highlighting, line numbers, and Git integration

Overview

Purpose

bat is a modern replacement for cat written in Rust. It adds syntax highlighting for over 200 languages, line numbers, Git change indicators, automatic paging for long files, and a non-printing character display mode. It is a drop-in upgrade for daily file viewing tasks.

Basic Syntax

bat [OPTIONS] [FILE]...

With no file argument, reads from stdin — making it a pipeline filter just like cat.

Key Strengths

bat shines for viewing source code, config files, scripts, and log files. Git integration shows uncommitted changes inline with + and ~ markers. The pager (less by default) activates automatically when output exceeds the terminal height. Works as a drop-in replacement in scripts with --plain mode to suppress decorations.

Installation

RHEL / CentOS / Fedora

# Fedora
dnf install bat

# RHEL 8/9 — via EPEL
dnf install epel-release
dnf install bat

Debian / Ubuntu

apt install bat

# Note: On some Debian/Ubuntu versions the binary is named batcat
# Create an alias if needed:
mkdir -p ~/.local/bin
ln -s /usr/bin/batcat ~/.local/bin/bat

From GitHub releases (any distro)

# Download latest .tar.gz from https://github.com/sharkdp/bat/releases
# Example for x86_64:
wget https://github.com/sharkdp/bat/releases/latest/download/bat-musl_x86_64.tar.gz
tar xzf bat-musl_x86_64.tar.gz
cp bat-*/bat ~/.local/bin/

# Verify
bat --version

Common Options

Option Description
-n, --number Show line numbers only (no other decorations)
-A, --show-all Show non-printing characters (tabs, spaces, line endings)
-p, --plain Plain output — no line numbers, no Git markers, no pager. Safe for scripts.
-l, --language Force syntax language: bat -l yaml config
-r, --line-range Show a line range: bat -r 20:40 file
--diff Show only Git-changed lines with surrounding context
--theme Choose a color theme: bat --theme=TwoDark file
--list-themes List all available themes with preview
--list-languages List all supported syntax languages
--pager Set the pager: --pager "less -RF" or --pager never
-H, --highlight-line Highlight a specific line: bat -H 42 file
--wrap Line wrapping: never, auto, or character

10 Detailed Examples

1
Basic File Viewing With Syntax Highlighting
bat /etc/ssh/sshd_config

What This Does:

Displays the file with automatic syntax detection, line numbers, a header showing the filename and language, and Git change markers if the file is in a repository. If the file is longer than your terminal, the pager activates automatically.

Compared to cat:

  • cat /etc/ssh/sshd_config — plain text, no highlighting, scrolls past the top
  • bat /etc/ssh/sshd_config — highlighted, numbered, paged, Git-aware
2
View a Specific Line Range
# Lines 50 through 80 only
bat -r 50:80 /var/log/syslog

# From line 100 to end of file
bat -r 100: /var/log/auth.log

# Just the first 25 lines
bat -r :25 /etc/nginx/nginx.conf

What This Does:

Displays only the specified line range with full syntax highlighting and correct line numbers showing the original file positions. Useful for jumping directly to a known problem area without scrolling through a large file.

SysAdmin Use Case:

vnu or a script tells you the error is on line 372 — go straight there: bat -r 365:380 problem-file.html

3
Show Git Changes Inline
# Show full file with Git change markers
bat deploy.sh

# Show only the changed lines with context
bat --diff deploy.sh

What This Does:

When viewing a file inside a Git repository, bat shows change markers in the left gutter: + for added lines, ~ for modified lines. The --diff flag filters to show only changed lines with surrounding context — like a git diff but with full syntax highlighting instead of raw diff output.

Practical Application:

Reviewing a config change before committing — see exactly what changed without switching to a separate diff tool.

4
Use as a Pipeline Filter
# Pipe command output through bat for highlighting
journalctl -u nginx --since "1 hour ago" | bat -l log

# Highlight grep output
grep -n "error" /var/log/syslog | bat -l log --plain

# Pretty-print a JSON API response
curl -s https://api.example.com/status | bat -l json

# View a man page with bat
man ssh | bat -l man --plain

What This Does:

bat reads from stdin when no file is given, making it a drop-in filter anywhere in a pipeline. The -l flag forces the syntax language since bat cannot auto-detect from a pipe. Use --plain to suppress line numbers and the pager when you want clean output for further processing.

Key Point:

bat auto-detects from filenames but needs -l when reading from a pipe. Common language names: log, json, yaml, bash, python, man.

5
Show Non-Printing Characters
# Show all non-printing characters
bat -A /etc/hosts

# Useful for spotting:
#   ^I  = tab character
#   $   = end of line (shows CRLF vs LF)
#   ·   = trailing spaces

What This Does:

The -A flag renders non-printing characters visibly. This is the bat equivalent of cat -A but with syntax highlighting intact. Invaluable for debugging config files that fail to parse due to invisible characters.

SysAdmin Use Cases:

  • Config file copied from Windows has CRLF line endings — bat -A shows the ^M
  • YAML file fails to parse — trailing spaces or tabs are the usual culprit
  • Shell script fails with "bad interpreter" — invisible character in the shebang line
6
View Multiple Files
# View several config files in sequence
bat /etc/ssh/sshd_config /etc/fail2ban/jail.conf /etc/hosts.allow

# Use a glob
bat /etc/nginx/conf.d/*.conf

# All Python files in current directory
bat *.py

What This Does:

bat displays multiple files sequentially, with a clear header between each showing the filename. Each file gets its own syntax detection. This is significantly more readable than cat file1 file2 which runs the files together with no separation.

Practical Application:

Reviewing all nginx vhost configs in one pass: bat /etc/nginx/sites-enabled/*

7
Force a Syntax Language
# A config file with no recognized extension
bat -l ini /etc/myapp/config

# A script with a non-standard extension
bat -l bash deploy.sh.bak

# Highlight a heredoc being built interactively
echo "SELECT * FROM users;" | bat -l sql

# Check what language bat detected
bat --language /etc/postfix/main.cf

What This Does:

bat detects syntax from file extensions and shebangs. When those are absent or misleading, -l overrides the detection. Run bat --list-languages to see all supported names.

Common Language Names:

  • bash, sh, zsh
  • python, ruby, perl
  • json, yaml, toml, ini
  • nginx, apache, ssh_config
  • sql, xml, html, css
  • log, man, diff
8
Themes — Choosing and Previewing
# See all themes with a live preview
bat --list-themes

# Use a specific theme for one command
bat --theme=TwoDark /etc/ssh/sshd_config

# Set a permanent theme in config
mkdir -p ~/.config/bat
echo '--theme="TwoDark"' >> ~/.config/bat/config

# Popular themes for terminal use:
# TwoDark      — dark, easy on the eyes
# gruvbox-dark — warm dark tones
# Coldark-Dark — high contrast dark
# Monokai Extended — classic dark
# GitHub       — light, familiar

What This Does:

bat ships with dozens of color themes. The --list-themes flag shows a live preview of each theme applied to a sample file so you can choose without guessing. Theme preference goes in ~/.config/bat/config to persist across sessions.

9
Persistent Configuration
# bat reads ~/.config/bat/config at startup
mkdir -p ~/.config/bat

cat > ~/.config/bat/config << 'EOF'
# Theme
--theme="TwoDark"

# Always show line numbers
--style="numbers,changes,header"

# Use less with follow mode available
--pager="less -RF"

# Wrap long lines
--wrap=never
EOF

# Verify config is loaded
bat --config-file

What This Does:

Any flag you use regularly can go in the config file — one flag per line. bat reads it automatically at startup. The --style option controls which decorations appear: numbers (line numbers), changes (Git markers), header (filename bar), grid (separator lines), full (everything).

Minimal Style Options:

  • --style=plain — no decorations, just highlighting
  • --style=numbers — line numbers only
  • --style=full — everything (default)
10
Integration With Other Tools
# Use bat as the man pager
export MANPAGER="sh -c 'col -bx | bat -l man -p'"
man grep

# Use bat as the git diff pager
git config --global core.pager bat

# fzf preview with bat (see fzf page for full setup)
export FZF_DEFAULT_OPTS="--preview 'bat --color=always {}'"
fzf

# Alias cat to bat (add to ~/.bashrc)
alias cat='bat --plain'

# Alias for plain output when scripting
alias batp='bat --plain --pager=never'

What This Does:

bat integrates cleanly into several common workflows. As a man pager it syntax-highlights manual pages. As the git pager it highlights diffs. The fzf integration provides a syntax-highlighted file preview panel. The cat alias gives you bat everywhere without changing your muscle memory.

Tip for Scripts:

Never alias bat to cat in scripts — use the explicit path or bat --plain --pager=never when you need guaranteed plain output for further processing. The alias is for interactive use only.

💡 ripgrep + bat — a natural pair

Use ripgrep to find the file and line, then bat to view the context: rg -l "pattern" | xargs bat -r :50 or jump to a specific hit: bat -r 45:55 $(rg -l "pattern" | head -1)

⚠️ bat vs. cat in scripts

bat is for human consumption. Its pager, colors, and decorations break pipelines in non-interactive scripts. Use plain cat in scripts. Use bat at the terminal. If you need bat in a pipeline, always add --plain --pager=never --color=never.

Quick Reference

Task Command
View a file bat filename
View lines 50–80 bat -r 50:80 filename
Show Git changes only bat --diff filename
Show non-printing chars bat -A filename
Plain output (no decorations) bat -p filename
Force syntax language bat -l yaml filename
Highlight a specific line bat -H 42 filename
List available themes bat --list-themes
List supported languages bat --list-languages
Pipe stdin through bat journalctl -u sshd | bat -l log
No pager bat --pager=never filename
View config file location bat --config-file