cat 命令详解与参数实测(Ubuntu 22.04)
cat 全参数实测:-n/-b 行号差异、-s 压缩空行、-A/-E/-T/-v 控制字符可视化、重定向生成与追加、多文件拼接合并,Ubuntu 22.04 coreutils 8.32 全部回显实测。
cat 命令详解与参数实测(Ubuntu 22.04)
目标:全面掌握 cat 的全部常用参数——
-n/-b两种行号模式的差异、-s压缩连续空行、-A/-E/-T/-v控制字符可视化、重定向>生成与>>追加、多文件拼接合并,全部命令与回显已在 Ubuntu 22.04(cat 属 GNU coreutils 8.32)实测通过。
一、环境信息
本节记录实测环境与演示数据,便于读者对照复现。cat 来自 GNU coreutils,是日常使用频率最高的文本工具之一,环境信息里同时给出演示目录与测试文件清单。
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- cat 版本:GNU coreutils 8.32(软件包 coreutils 8.32-4.1ubuntu1.4,见 2.3 实测)
- 演示目录:
/root/demo/cat/ - 测试数据:短文本
short.txt、含空行的编号演示文件num.txt(7 行)、连续空行文件blank.txt(10 行)、长文本long.txt(35 行)、含制表符/无尾换行的tabs.txt、CRLF 行尾的dos.txt、含 ANSI 转义序列的esc.txt、拼接样例a.txt/b.txt/c.txt
二、命令概览
2.1 语法与测试数据准备
cat 的名字取自 concatenate(拼接),核心职责是把文件按顺序读到标准输出:不跟参数时读标准输入,跟多个文件时按顺序拼接。帮助原文给出的语法是 cat [OPTION]... [FILE]...,即「选项 + 任意多个文件」。它不做分页、不加过滤,输出什么完全取决于参数。
先准备一套覆盖「短文本、空行、长文本、控制字符、多文件」的演示数据,后续所有参数实测都基于这套数据:
printf "alpha\nbeta\ngamma\n" > /root/demo/cat/a.txt
printf "one\ntwo\nthree\n" > /root/demo/cat/b.txt
printf "first\nsecond\nthird\n" > /root/demo/cat/c.txt
cat > /root/demo/cat/short.txt <<EOF
hello cat
this is a short demo file
used for basic option testing
EOF
cat > /root/demo/cat/num.txt <<EOF
line one
line two
line three
line four
line five
EOF
cat > /root/demo/cat/blank.txt <<EOF
first line
after two blank lines
after three blank lines
last line
EOF
printf "cat demo line %02d\n" $(seq 1 35) > /root/demo/cat/long.txt
printf "col1\tcol2\tcol3\nno newline at end" > /root/demo/cat/tabs.txt
printf "dos line one\r\ndos line two\r\n" > /root/demo/cat/dos.txt
printf "normal text\n\033[31mred text\033[0m\nnormal again\n" > /root/demo/cat/esc.txt
验证数据就绪——10 个文件全部生成,long.txt 35 行、num.txt 7 行(含 2 个空行)、blank.txt 10 行(含 2 处连续空行):
$ ls -l /root/demo/cat
total 40
-rw-r--r-- 1 root root 17 Oct 15 07:42 a.txt
-rw-r--r-- 1 root root 14 Oct 15 07:42 b.txt
-rw-r--r-- 1 root root 73 Oct 15 07:42 blank.txt
-rw-r--r-- 1 root root 19 Oct 15 07:42 c.txt
-rw-r--r-- 1 root root 28 Oct 15 07:42 dos.txt
-rw-r--r-- 1 root root 43 Oct 15 07:42 esc.txt
-rw-r--r-- 1 root root 595 Oct 15 07:42 long.txt
-rw-r--r-- 1 root root 51 Oct 15 07:42 num.txt
-rw-r--r-- 1 root root 66 Oct 15 07:42 short.txt
-rw-r--r-- 1 root root 32 Oct 15 07:42 tabs.txt
$ wc -l /root/demo/cat/long.txt /root/demo/cat/num.txt /root/demo/cat/blank.txt
35 /root/demo/cat/long.txt
7 /root/demo/cat/num.txt
10 /root/demo/cat/blank.txt
52 total
2.2 --help 全量回显
cat --help 列出全部参数。cat 的参数量不大,但组合灵活(-A 等于 -vET 的缩写),先把帮助原文完整收录:
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-A, --show-all equivalent to -vET
-b, --number-nonblank number nonempty output lines, overrides -n
-e equivalent to -vE
-E, --show-ends display $ at end of each line
-n, --number number all output lines
-s, --squeeze-blank suppress repeated empty output lines
-t equivalent to -vT
-T, --show-tabs display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version output version information and exit
Examples:
cat f - g Output f's contents, then standard input, then g's contents.
cat Copy standard input to standard output.
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'
💡 说明:注意帮助里的两个细节——其一,
-b明确标注 "overrides -n"(同时给出时以-b为准);其二,-u是被忽略的兼容参数(POSIX 历史遗留)。-e、-t是给-v叠加功能的组合缩写,正文逐项实测-v系列时对照理解。
2.3 版本确认
确认 cat 的归属与版本,与 Ubuntu 22.04 仓库里的 coreutils 版本对应:
$ cat --version | head -1
cat (GNU coreutils) 8.32
输出 cat (GNU coreutils) 8.32,即本文全部回显均来自 coreutils 8.32 的实现。
三、参数逐项实测
3.1 无参数:默认拼接输出
不带任何参数时,cat 把文件内容原样输出——不编号、不分页、不修改任何字节。先用短文件看基本行为:
$ cat /root/demo/cat/short.txt
hello cat
this is a short demo file
used for basic option testing
再用 35 行的 long.txt 确认默认行为对长文件也是「一口气全量输出」:
$ cat /root/demo/cat/long.txt
cat demo line 01
cat demo line 02
cat demo line 03
cat demo line 04
cat demo line 05
cat demo line 06
cat demo line 07
cat demo line 08
cat demo line 09
cat demo line 10
cat demo line 11
cat demo line 12
cat demo line 13
cat demo line 14
cat demo line 15
cat demo line 16
cat demo line 17
cat demo line 18
cat demo line 19
cat demo line 20
cat demo line 21
cat demo line 22
cat demo line 23
cat demo line 24
cat demo line 25
cat demo line 26
cat demo line 27
cat demo line 28
cat demo line 29
cat demo line 30
cat demo line 31
cat demo line 32
cat demo line 33
cat demo line 34
cat demo line 35
35 行一次刷完。cat 的定位是字节流搬运工:给多少字节就吐多少字节,屏幕上能否看完不归它管。
💡 技术拓展:查看文本内容的工具不止 cat 一个,常用命令的定位对比如下——
命令 原理/特点 适用场景 cat全量输出,支持拼接与重定向 小文件、管道供数、合并文件 more整屏分页,可空格翻页、q 退出 快速翻看中等长度文件 less分页 + 前后滚动 + 搜索,功能强于 more 大文件交互浏览 head/tail只取头/尾部若干行 看文件开头/结尾、跟踪日志 grep按模式过滤行 只关心匹配行时 日常读小文件用 cat 最直接;面对大文件或需要翻页搜索时,应换用 less/more 交互浏览,避免长输出刷屏。本文实测以 cat 为主线,more 与 less 的实测差异见本专栏《more 命令详解与参数实测(Ubuntu 22.04)》。
3.2 -n:所有输出行编号
-n(--number)给所有输出行加行号——空行也占一个号。用含 2 个空行的 num.txt 观察:
$ cat -n /root/demo/cat/num.txt
1 line one
2 line two
3
4 line three
5
6 line four
7 line five
第 3、5 行是空行,但行号照样递增分配(行号后跟制表符再接内容,空行只显示号)。对 35 行长文件同样成立(输出节选,实测首尾):
$ cat -n /root/demo/cat/long.txt
1 cat demo line 01
2 cat demo line 02
3 cat demo line 03
4 cat demo line 04
5 cat demo line 05
(中间略:第 6~30 行依序编号,同上格式)
33 cat demo line 33
34 cat demo line 34
35 cat demo line 35
行号区固定 6 列宽、右对齐,编号与内容之间是一个制表符。
💡 提示:
cat -n的行号是「输出行号」,管道里它给流经的数据编号,常用于cat -n file | head -20这类组合,也常被放进管道中间定位第几行。
3.3 -b:跳过空行编号(与 -n 的差异)
-b(--number-nonblank)只给非空行编号,空行不占号。同一个 num.txt,与 3.2 的 -n 逐行对照:
$ cat -b /root/demo/cat/num.txt
1 line one
2 line two
3 line three
4 line four
5 line five
差异一目了然:-n 把空行编为 3、5,内容行编到 7;-b 里空行保持空白、不编号,最后一行 line five 是 5 号而非 7 号。帮助原文也写明 -b 会覆盖 -n("overrides -n")——两者同时给时只有 -b 生效。
💡 提示:需要「有效内容行数」时用
-b;需要与编辑器/nl -b a一致的绝对行号(空行也有号,方便定位)时用-n。
3.4 -s:压缩连续空行
-s(--squeeze-blank)把连续多个空行压成一行。先看 blank.txt 原始内容(两处连续空行:2 连与 3 连):
$ cat /root/demo/cat/blank.txt
first line
after two blank lines
after three blank lines
last line
加 -s 后输出:
$ cat -s /root/demo/cat/blank.txt
first line
after two blank lines
after three blank lines
last line
两处连续空行都被压成了单个空行,行数从 10 降到 6。-s 只压缩连续空行,单个空行原样保留。
💡 提示:清理人工编辑留下的连续空行,
cat -s 原文件 > 新文件是最轻量的做法;若要把连续空行彻底删除(一个不留),得换grep -v '^$'或sed '/^$/d'。
3.5 -A:显示全部控制字符
-A(--show-all)等价于 -vET:非打印字符用 ^/M- 记法显示、行尾加 $、制表符显示为 ^I。它是排查「看不见的字符」的利器。先看含制表符且末行无换行的 tabs.txt:
$ cat -A /root/demo/cat/tabs.txt
col1^Icol2^Icol3$
no newline at end
两个关键发现:其一,col1 与 col2 之间的空白其实是制表符,显示为 ^I;其二,第二行末尾没有 $——因为这个文件最后没有换行符(生成时用的 printf 未带 \n),$ 只标在真正的换行处。再看 CRLF 行尾的 dos.txt:
$ cat -A /root/demo/cat/dos.txt
dos line one^M$
dos line two^M$
每行行尾都是 ^M$:^M 是回车符 CR(\r),$ 是换行符 LF(\n)的位置。Windows 风格的 CRLF 行尾在 Linux 下常导致脚本不执行、grep 匹配不上,用 cat -A 一眼就能识别。
💡 提示:把 Windows 拷来的文件
dos2unix 文件名转换即可去掉^M;没有 dos2unix 时sed -i 's/\r$//' 文件名等效。
3.6 -E:只在行尾显示 $
-E(--show-ends)是 -A 的子集,只在每个换行处显示 $,不转换其他控制字符:
$ cat -E /root/demo/cat/dos.txt
dos line one$
dos line two$
对比 3.5 的 -A 回显(dos line one^M$):-E 的输出里 CR 字节仍在(原样字节流),只是没有被翻译成 ^M 可视化。终端上 CR 会让光标回到行首,$ 实际打在行首位置;日志/管道采集时则表现为上面这样紧跟在行内容后。要完整看见 CR,用 -A 或 -v。
💡 提示:只想确认「每行是否以换行结尾、有没有尾随空格」时
-E足够;要排查 CR/Tab 等不可见字符,直接上-A。
3.7 -T:把制表符显示为 ^I
-T(--show-tabs)专把 Tab 显示成 ^I,行尾不加 $、CR 不转换:
$ cat -T /root/demo/cat/tabs.txt
col1^Icol2^Icol3
no newline at end
与 3.5 的 -A 回显对比:^I 保留,但行尾 $ 消失。这就是帮助里 -t 等价于 -vT 的含义——-T 只负责制表符这一件事。写 Makefile(命令行必须以 Tab 开头)或排查列对齐问题时,-T 能立刻区分 Tab 与空格。
💡 提示:
grep -P '\t'可筛出含 Tab 的行;把 Tab 统一换成空格用expand 文件名,反向用unexpand。
3.8 -v:非打印字符的 ^ / M- 记法
-v(--show-nonprinting)把非打印字符按 ^(控制字符)与 M-(高位字节)记法显示,但按帮助原文不处理 LFD(换行)与 TAB。esc.txt 里埋了一段 ANSI 颜色转义序列(\033[31m…\033[0m):
$ cat -v /root/demo/cat/esc.txt
normal text
^[[31mred text^[[0m
normal again
ESC 字符(\033)被显示为 ^[,所以那行变成 ^[[31mred text^[[0m——这就是终端颜色代码的「素颜」。直接 cat 该文件时终端会渲染出红色,-v 让它现出原形。再看 tabs.txt:
$ cat -v /root/demo/cat/tabs.txt
col1 col2 col3
no newline at end
Tab 原样输出(-v 明确排除 TAB),CR 等其他控制字符才会被转成记法。三个参数的覆盖关系:-v 转义非打印字符(不含 Tab/换行)、-T 补上 Tab、-E 补上行尾 $,三者叠加即 -A。
💡 提示:日志里混入 ANSI 颜色码导致 grep/排序异常时,
cat -v 日志 | grep 关键词或sed 's/\x1b\[[0-9;]*m//g'都能去掉颜色干扰。
四、实战示例
4.1 重定向 > 生成与 >> 追加
cat 最经典的搭档是重定向。> 把输出写入文件(文件不存在则创建,存在则清空重写):
$ echo "created by redirect" > /root/demo/cat/redir.txt
$ cat /root/demo/cat/redir.txt
created by redirect
>> 在文件末尾追加,不清空原有内容:
$ echo "appended by redirect" >> /root/demo/cat/redir.txt
$ cat /root/demo/cat/redir.txt
created by redirect
appended by redirect
两行内容都在,>> 只往尾部添加。日常的 cat > 文件 <<EOF … EOF(heredoc 写入多行)正是 > 重定向与 cat 读标准输入的组合。
4.2 多文件拼接与合并
cat 跟多个文件参数时按顺序拼接输出。两个文件直接连读:
$ cat /root/demo/cat/a.txt /root/demo/cat/b.txt
alpha
beta
gamma
one
two
three
配合 > 把多个文件合并成一个新文件(原文件不动):
$ cat /root/demo/cat/a.txt /root/demo/cat/b.txt /root/demo/cat/c.txt > /root/demo/cat/merged.txt
$ cat /root/demo/cat/merged.txt
alpha
beta
gamma
one
two
three
first
second
third
$ wc -l /root/demo/cat/merged.txt
9 /root/demo/cat/merged.txt
三个 3 行文件合并成 9 行的 merged.txt。这也是「cat = concatenate」的本义:日志按日期切割后用 cat access.log.* > access.log.all 合并还原,是运维里的高频用法。
💡 提示:帮助原文的示例
cat f - g表示先输出 f,再读一段标准输入(-占位),再输出 g——-可以插在文件序列的任意位置,常用于zcat a.gz | cat - b.txt这类拼接。
五、注意事项与常见问题
Q1:cat -n 和 cat -b 同时使用时到底以谁为准?
以 -b 为准。帮助原文在 -b 上明确标注 "overrides -n"(见 2.2),且 -b 与 -n 是同类参数(行号编号),后给的 -b 会覆盖 -n,实测见 3.2/3.3 对照。
Q2:cat -A 输出里的 ^M 是什么?怎么去掉?
^M 是回车符 CR(\r),来自 Windows 风格的 CRLF 行尾(见 3.5 实测)。它会让 shell 脚本报「bad interpreter」、grep 匹配失败。用 dos2unix 文件名 或 sed -i 's/\r$//' 文件名 转换为 LF 即可。
Q3:为什么 cat 文件 后 shell 提示符紧跟在内容后面没有换行?
文件最后一行没有换行符(见 3.5 中 no newline at end 后没有 $ 的实测)。cat 原样输出字节流,不替文件补 \n;用 cat -A 可以确认。规范生成文件时记得结尾带换行。
Q4:读一个几个 GB 的大日志,cat 会把内存撑爆吗?
不会。cat 是流式读写,边读边写不缓存整个文件,内存占用恒定。问题在于刷屏:几 GB 输出人眼没法看。大文件浏览应改用 less(支持前后滚动与搜索)或 tail -n 100 只看尾部(见 3.1 拓展表)。
Q5:cat > 文件 敲完命令终端卡住不动了?
这是 cat 在读标准输入(帮助原文:With no FILE, or when FILE is -, read standard input)。你敲的每个字符会被原样回显,按 Ctrl+D 结束输入即可。写多行文件推荐明确写 cat > 文件 <<EOF,用 EOF 结束,见 4.1。
Q6:-s 能把所有空行都删掉吗?
不能。-s 只把连续空行压缩成一行,单个空行保留(见 3.4 实测)。要删除全部空行用 grep -v '^$' 或 sed '/^$/d'。
六、参考链接
- GNU coreutils 官方手册(cat 章节):https://www.gnu.org/software/coreutils/manual/html_node/cat-invocation.html
- 在线文档:https://www.gnu.org/software/coreutils/cat
- 本机帮助:
cat --help、man cat、info '(coreutils) cat invocation'(Ubuntu 22.04 内置)