32blogby Studio Mitsu

bat: el cat moderno con resaltado de sintaxis y Git

bat es un reemplazo de cat escrito en Rust con resaltado de sintaxis, sidebar de diff Git y paginación automática. Instalación, configuración y usos diarios.

by omitsu14 min read
Contenido

bat es un reemplazo directo de cat escrito en Rust que añade resaltado de sintaxis para más de 200 lenguajes, un sidebar con el diff de Git, paginación automática mediante less y temas configurables. Se instala con el gestor de paquetes de tu sistema (apt install bat, brew install bat o winget install sharkdp.bat), añades alias cat='bat --paging=never' en tu shell y obtienes un visor de archivos dramáticamente mejor sin cambiar tus hábitos.

Seguro que ya lo notaste: cat archivo.py en una terminal moderna se ve como si siguiéramos en 1983. Sin colores, sin números de línea, sin pistas de qué líneas cambiaron en el último commit. Si el archivo es largo, pasa volando y lo pierdes. Al final pulsas flecha arriba, lo abres con less, y encima less te devuelve un monocromo que ignora el tema que configuraste con tanto esmero.

Esa fricción es justamente lo que resuelve bat. No es una idea nueva — los visores con resaltado de sintaxis existen desde hace años — pero bat es el que cuajó, porque se comporta como cat, es suficientemente rápido para aliasarlo sin pensarlo, y su salida por defecto ya resulta agradable. Este artículo va más allá del "instálalo y listo" y cubre el archivo de configuración, la integración con Git y la media docena de integraciones que convierten a bat en el centro silencioso de una shell moderna.

Los cuatro problemas que cat nunca resolvió

cat viene de concatenate, y nació en 1971 para unir archivos y enviar el resultado a la salida estándar. Usarlo para ver un archivo siempre fue un efecto colateral que resultó cómodo. Todo lo que te molesta de cat hoy es síntoma de pedirle a una herramienta de concatenación que haga el trabajo de un visor.

bat arregla cuatro cosas concretas que cat nunca iba a solucionar:

  1. Resaltado de sintaxis. cat nunca parsea el contenido, así que no puede pintar un literal de cadena en azul y una palabra clave en magenta. bat trae más de 200 definiciones de sintaxis compiladas, usando el mismo formato .sublime-syntax que Sublime Text.
  2. Números de línea, cabecera y rejilla. cat -n te da los números y poco más. bat muestra una cabecera con el nombre del archivo, una rejilla que separa cabecera de contenido y los números en una columna atenuada — se ve como una herramienta de code review.
  3. Paginación automática. Si el archivo es más largo que la terminal, cat lo vuelca y pierdes el principio. bat detecta si hay una TTY real y pasa la salida a less con las flags correctas. Cuando se conecta a una tubería, vuelve a salida plana sin que tengas que tocar nada.
  4. Integración con Git. bat lee .git y marca qué líneas se añadieron, modificaron o borraron en la canaleta izquierda — los mismos símbolos que ves en VS Code. Esto por sí solo ya justifica la instalación.

Instalar bat (y el asunto de batcat)

La instalación es un solo comando, pero en Ubuntu/Debian hay una trampa que conviene conocer.

powershell
# winget (integrado en Windows 11)
winget install sharkdp.bat

# Chocolatey
choco install bat

# Scoop
scoop install bat

En Windows, bat funciona en PowerShell, Windows Terminal y WSL. Para color de 24 bits usa Windows Terminal, que soporta truecolor de forma nativa.

Después de instalar, comprueba la versión y echa un vistazo a bat --help una vez. Es la forma más rápida de ver todas las flags juntas.

bash
bat --version
# bat 0.26.1 o más reciente

bat --help | less

Nueve patrones diarios que reemplazan a cat

La mayor parte del tiempo usas bat igual que usas cat: bat archivo. Pero hay nueve variantes pequeñas que cubren casi todos los casos reales. Memorízalas y rara vez necesitarás otra cosa.

bash
# 1. Ver un archivo con resaltado y paginación (comportamiento por defecto)
bat src/app.ts

# 2. Ver varios archivos (como cat a b c)
bat README.md package.json src/main.ts

# 3. Concatenar con stdin en medio, como hace cat
echo "--- cabecera ---" | bat cabecera.md - pie.md

# 4. Forzar un lenguaje cuando la extensión es inusual
bat -l json config.txt
bat -l dockerfile Containerfile

# 5. Mostrar solo un rango de líneas (ideal para citar en issues)
bat --line-range=42:80 src/handlers.ts
bat --line-range=:50 README.md   # primeras 50 líneas

# 6. Salida plana sin decoraciones — el reemplazo directo de cat
bat -p src/app.ts
bat --plain --paging=never src/app.ts

# 7. Mostrar caracteres invisibles (tabs, espacios al final, CRLF)
bat -A Makefile

# 8. Recibir de una tubería y fijar el lenguaje explícitamente
curl -s https://api.github.com/repos/sharkdp/bat | bat -l json

# 9. Mostrar solo las líneas que Git considera cambiadas
bat --diff src/app.ts

El que uso con diferencia es --line-range. Cuando alguien pregunta en Slack "¿qué hace esa función sobre la línea 200?", pasar bat --line-range=190:220 ruta/al/archivo.ts al portapapeles da un extracto con números de línea y resaltado listo para pegar en un issue.

Configurar bat una vez en ~/.config/bat/config

Pasar flags cada vez cansa rápido. bat lee un archivo de configuración donde cada línea es una flag de línea de comandos — exactamente lo que escribirías después de bat en el terminal. Este archivo es el que convierte bat de "herramienta curiosa" en "infraestructura permanente" de tu shell.

Primero averigua dónde está la configuración:

bash
bat --config-file
# Linux:   /home/tu-usuario/.config/bat/config
# macOS:   /Users/tu-usuario/.config/bat/config
# Windows: C:\Users\tu-usuario\AppData\Roaming\bat\config

bat --generate-config-file
# Crea el archivo con el contenido por defecto si no existe

Una configuración inicial realista para alguien que trabaja con varios lenguajes:

bash
# ~/.config/bat/config

# Tema oscuro que encaja con la mayoría de fondos de terminal
--theme="OneHalfDark"

# Números de línea y cambios de Git, pero sin cabecera ni rejilla
--style="numbers,changes"

# Tabulación de 2 espacios (estándar moderno en JS/TS)
--tabs=2

# Asociar nombres de archivo específicos a sintaxis concretas
--map-syntax=".ignore:Git Ignore"
--map-syntax="*.conf:INI"
--map-syntax="Dockerfile.*:Dockerfile"

# Pager personalizado: less con flags razonables
--pager="less -FR"

En cuanto este archivo existe, cada invocación de bat aplica esos valores por defecto. Aún puedes sobrescribir cualquier flag en la línea de comandos — por ejemplo bat --theme=GitHub README.md para una vista clara puntual.

Temas

bat incluye unos 25 temas. Lístalos con previsualización:

bash
bat --list-themes

Cada entrada de la lista va seguida de una muestra de código, así puedes ver cómo queda sobre el fondo de tu terminal antes de decidir. Mi recomendación por defecto es OneHalfDark para terminales oscuros y GitHub para claros, pero es una cuestión de gusto. Si tienes un .tmTheme de Sublime Text, colócalo en $(bat --config-dir)/themes/ y ejecuta bat cache --build.

Variables de entorno

Todo lo que hay en el archivo de configuración tiene un equivalente en variables de entorno, útil para cambios puntuales por shell o por proyecto:

VariableEquivalente aUso típico
BAT_THEME--theme=...Cambiar de tema por terminal o por proyecto
BAT_STYLE--style=...Estilo mínimo (plain) en scripts, completo en shells interactivas
BAT_PAGER--pager=...Usar otro pager en un entorno concreto
BAT_PAGING--paging=...Forzar never cuando quieres comportamiento tipo cat
BAT_CONFIG_PATHApuntar a un archivo de configuración local del proyecto

La lista completa está en la sección de customization del README.

Integración con Git: el sidebar de diff y el modo --diff

A bat no hay que decirle que existe Git. Si entras en un repositorio y ejecutas bat archivo.rs, verás una columna con marcadores +, ~ o - en la canaleta izquierda junto a cada línea añadida, modificada o borrada respecto a HEAD. Internamente usa git2, los bindings de libgit2 para Rust, para leer el estado del repo directamente.

Hay dos formas de aprovechar esto:

bash
# 1. Pasivo: los marcadores aparecen si --style incluye "changes"
bat src/app.ts

# 2. Activo: imprime solo las líneas que Git considera modificadas
bat --diff src/app.ts

Combinando bat --diff con xargs obtienes un "muéstrame todo lo que he cambiado, con resaltado" instantáneo:

bash
git diff --name-only -z | xargs -0 bat --diff

Si quieres que bat colorée también git log y git show, la herramienta adecuada es delta, un visor de diffs especializado en Rust. Tenemos una guía completa de delta en esta misma serie — es la opción superior cuando el modo --diff de bat se queda corto.

Integraciones: man, fzf, ripgrep y less

La razón por la que bat termina en el centro de una shell moderna es que casi cualquier otra CLI puede hablar con él. Estas cuatro integraciones se amortizan en una semana.

Páginas man con resaltado

Define MANPAGER como un comando de shell que limpia las secuencias ANSI crudas de man y canaliza el resultado a través de bat:

bash
# Añade a ~/.bashrc o ~/.zshrc (en Debian/Ubuntu cambia `bat` por `batcat`)
export MANPAGER="sh -c 'awk '\''{ gsub(/\x1B\[[0-9;]*m/, \"\", \$0); gsub(/.\x08/, \"\", \$0); print }'\'' | bat -p -lman'"

A partir de ahí, man ffmpeg, man git o man bash salen con secciones coloreadas, opciones en negrita y flags resaltadas. El snippet está documentado en la sección de highlighting --help messages del README y es de esos cambios de los que no se vuelve atrás.

Previsualizaciones en fzf

fzf es un fuzzy finder con una flag --preview que ejecuta un comando por cada candidato. Apuntarla a bat te da previsualizaciones con sintaxis resaltada:

bash
# En ~/.bashrc o ~/.zshrc
export FZF_DEFAULT_OPTS="--preview 'bat --color=always --style=numbers --line-range=:500 {}'"

Aquí --color=always es crítico. fzf ejecuta el comando de preview con la salida conectada a una tubería, no a una TTY, así que bat por defecto desactivaría el color. Forzarlo es lo que hace que la previsualización funcione. El --line-range=:500 evita que bat intente renderizar un archivo de 10 000 líneas cada vez, que se nota lento.

Visor para la salida de ripgrep

ripgrep tiene su propio artículo, pero se combina con bat a través del wrapper batgrep incluido en bat-extras. batgrep foo busca foo con ripgrep y muestra cada coincidencia con el resaltado de bat y unas cuantas líneas de contexto. Es lo más cerca que vas a estar de un "ir a definición" en CLI.

less, pero mejor

bat ya usa less como pager, pero puedes invertir la relación: hacer que less delegue en bat mediante LESSOPEN:

bash
# ~/.bashrc
export LESSOPEN="|bat --color=always --style=numbers --paging=never %s"
export LESS="-R"

Ahora cualquier herramienta que llame a less sobre un archivo — git show, systemctl cat, journalctl — recibe la salida coloreada por bat de regalo. Es una configuración avanzada y ocasionalmente entra en conflicto con otras herramientas que asumen que less es "tonto", así que actívala a conciencia y retírala si algo se rompe.

FAQ

¿Es bat un reemplazo total de cat?

Para ver archivos en una shell interactiva, sí. Para scripts que dependen de salida byte a byte, no — deja cat real en los scripts. El patrón seguro es aliasar bat sobre cat solo en shells interactivas. Poner alias cat='bat --paging=never' en .bashrc es seguro porque .bashrc no se carga en shells no interactivas.

¿Por qué bat no muestra colores cuando paso su salida por una tubería?

bat detecta automáticamente si la salida estándar es una TTY. Al conectarla a una tubería asume que quieres salida plana y apaga los colores. Para forzar los colores a través de una tubería, usa --color=always. Es la misma convención que siguen ls y grep.

¿Cómo configuro bat como pager por defecto de Git?

Ajusta el pager de Git a un comando que pase por bat:

bash
git config --global core.pager "bat --plain"

Si quieres un visor de diffs en condiciones, con vista lado a lado y números de línea, delta es la opción superior. bat como pager de Git funciona y es ligero, pero no es la mejor herramienta para el trabajo.

¿bat respeta el tema de mi terminal?

Parcialmente. bat elige tema de su propia lista incluida — no lee la paleta de 16 colores de tu terminal como hace ls --color=auto. Si quieres que case con un tema concreto, elige uno de bat --list-themes que combine con tu terminal, o combina BAT_THEME_DARK y BAT_THEME_LIGHT con la variable COLORFGBG para cambiar automáticamente entre terminales claros y oscuros.

¿bat es más lento que cat en archivos grandes?

Medible sí, en la práctica no. En un log de 100 MB, cat es claramente más rápido porque no parsea nada mientras bat analiza cada línea. En uso normal — código fuente, archivos de configuración, READMEs — la diferencia es imperceptible. Para archivos enormes, usa bat --plain --paging=never o directamente cat y listo.

¿Puedo añadir mis propias sintaxis o temas?

Sí. Coloca archivos .sublime-syntax en $(bat --config-dir)/syntaxes/ y archivos .tmTheme en $(bat --config-dir)/themes/, y luego reconstruye la caché:

bash
bat cache --build

Puedes importar la mayoría de temas y sintaxis de Sublime Text directamente. La sección de añadir sintaxis del README recorre el proceso completo.

Si ya tengo less con resaltado, ¿para qué sirve bat?

less no trae resaltado de sintaxis de serie — puedes atornillarlo con trucos de LESSOPEN, pero eso es exactamente el tipo de configuración que bat te regala lista. bat es como se verían cat y less si se diseñaran hoy.

Conclusión

Si esta semana instalas una sola herramienta de la lista de CLI modernas en Rust, que sea bat. Treinta segundos para instalarla, es un reemplazo directo que no rompe nada, y tras un día de uso la salida estilo cat del resto de herramientas empieza a sentirse vieja. Esa sensación es la señal silenciosa de que el upgrade de CLI salió bien.

Donde está la verdadera palanca es en el archivo de configuración. Dedícale diez minutos a ~/.config/bat/config — elige tema, decide el estilo, mapea tus nombres de archivo raros a la sintaxis adecuada — y luego olvídate del tema. Las integraciones con MANPAGER y fzf son bonus que cuestan dos líneas de shell cada una y se amortizan cada día que trabajas en el terminal.

Si te interesa el motivo técnico por el que bat, ripgrep y fd corren más que sus equivalentes clásicos, lee Por qué las CLI de Rust son tan rápidas. Si lo que quieres es un mapa de qué comando clásico sustituye cada herramienta moderna, ve al mapa de herramientas CLI. Y si estás reconstruyendo tu shell desde cero, la guía de dotfiles y entorno es el lugar donde centralizar los snippets de este artículo para que te sigan entre máquinas.