📌 项目地址:https://github.com/sharkdp/bat | ⭐ 近 50000 | 📜 MIT / Apache 系开源许可(以仓库为准)
先交代结论:我给 cat 设过 alias cat=bat,坚持两周后删掉了。但日常读文件,bat 我一直在用。这篇文章说清楚这两件事为什么不矛盾。
cat 和 bat 不是同一个赛道
cat 是管道的一环,输出要喂给下一个程序。bat 的终点是人的眼睛。
分清这一点,两个工具就能共存。强行替换反而出事,后面讲我踩的坑。
读文件时它好在哪
读 YAML、JSON、TOML,cat 靠肉眼数缩进,bat 按语法着色。key、value、字符串、数字分开标记,扫一眼就能定位问题。我读 GitHub Actions 的 workflow 时感受最明显,嵌套的 YAML 列表不用再皱着眉看。
bat 支持上百种语言和标记格式的高亮,语法定义来自 Sublime Text 的语法文件。文件类型判断不准时,可以用 -l 手动指定:
bat -l yaml .github/workflows/release.txt
在 git 仓库里,bat 还能标记未提交的改动行,由 --style=changes 控制,默认关闭:
bat --style=numbers,changes src/main.rs
numbers 开行号,changes 开 git 改动标记。它跟 git diff 的区别:bat 显示完整文件上下文,不用来回对照两份文件。改完代码想快速确认现状,这个更直接。
bat 自带分页器,长文件不用再手动接 less。
给 fzf 当预览器
README 里有一段标准写法:
fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}'
--color=always 是必须的,fzf 需要 bat 输出颜色码,预览窗口才有高亮。反过来,如果是 bat file.txt | grep xxx 这种管道用法,不用加这个参数,bat 检测到输出不是终端会自动关颜色。
--line-range=:500 限制预览行数。不加的话,遇到大文件,fzf 的光标移动会变卡。
脚本里别用它
这是我删掉别名的原因,两条主因,一个次要因素。
一是转义码污染。 cat file.txt | grep something 换成 bat,忘记加 --color=never,grep 的输出里就混进 ANSI 转义码。一两个文件无所谓,循环几百个文件时这些码会污染后续逻辑,排查起来很费劲。
二是启动开销。 bat 要做语法分析、颜色计算,单次比 cat 慢几十毫秒。循环 300 次就是秒级的差距,脚本跑得越勤亏得越多。
三是环境兼容的边角问题。 管道或 chroot 环境里,bat 偶尔拿不到终端宽度,输出会出问题。设 BAT_THEME=ansi 可以缓解,但每换一个环境就得重新配一次,不值得。
我的配置
~/.bat/config:
--theme="OneHalfDark"
--style="numbers,changes"
--pager="less -RF"
less -RF 让分页器支持搜索,退出后屏幕内容不残留。主题用 bat --list-themes 自己挑,我选了 OneHalfDark。
两个别名:
alias cb=bat
alias cat=cat
读代码敲 cb,写脚本用 cat,互不打扰。比强行替换别名省心多了。
要不要装
macOS 用 brew install bat,Debian/Ubuntu 用 apt install bat,注意装完二进制叫 batcat,需要自己做个软链或别名。其他平台也有对应的包管理器安装方式,README 里列得很全。
装完跑一下 bat ~/.bashrc 看效果,不满意就删。生产环境装不了新软件?cat | less 也够用,只是没高亮和行号。
bat 的核心价值很单纯:读文件时眼睛省力。这个价值够我留下它,但不够替换 cat。