Linux如何使用fmt格式化文本段落

作者:技术拾光

时间:2026-07-06

浏览:339

fmt是Linux的文本段落整理工具,通过空行识别段落并自动合并短行、折行长行。直接格式化无空行文件会挤成一行,可加-s和-w选项解决。-p选项严格匹配行首前缀,需清理前置空格。-c和-t分别处理首行顶格或缩进,依赖原始缩进结构。管道输入需避免ANSI转义和未引用变量。

文章目录

fmt 是 Linux 系统下一款专用于整理文本段落的小工具。它能够读取文本、识别段落、合并短行、折行长行,同时保留空行分隔——无需额外参数,即可将杂乱的文本自动整理为规整的段落。

然而实际使用中,常常会遇到各种问题。不少用户第一次使用 fmt 时就碰了壁:文件格式化后反而全部挤成了一行;处理代码注释时加上 -p 参数,前缀却丢失了;管道输入时输出错位难以阅读。这些正是 fmt 容易被误解的地方,下面逐一说明。

直接格式化文件时,为什么输出会乱成一行?

这不是 fmt 的 bug,而是它的默认行为:它会把每个逻辑段落——即用空行分隔的文本块——先压缩成单行,再重新排列。如果你看到“所有内容挤在一行”,说明原始文本中根本没有空行,fmt 自然将整篇内容视为同一个段落处理。

那么,如何排查?使用 cat -A file.txt 查看文件,就能知道源文件中是否存在 ^M 或空白行。如果确实没有空行,又希望强制按物理行切分,可以添加 -s 选项——它只负责拆分而不重新组合——再配合 -w 指定宽度,例如 fmt -s -w 60 file.txt。另外,如果原始文本中混入了制表符或混合空格缩进,fmt 可能误判段落边界,建议先用 sed 's/^[[:space:]]*//' 清理首部空格后再尝试。

处理代码注释时,-p 选项为什么会丢前缀?

-p 要求前缀严格匹配行首,否则会被忽略。格式化之后,fmt 会自动为每行重新加上这个前缀——前提是整个行都以该前缀开头,且前面没有空格。很多人在这一点上栽了跟头。

常见失败场景有三种:第一,注释写成“ # long comment”,前面多了空格,fmt -p '# ' 自然不会生效。解决办法是先执行 sed 's/^ * #/#/' 去掉空格。第二,前缀本身包含空格,例如“# ”,必须写成 -p '# ',少写一个空格或引号未闭合都会报 invalid option。第三,多行注释中混用了 # 和 //,fmt 一次只能处理一种前缀,需要分两次调用才能覆盖所有情况。

-c 和 -t 都表示保留缩进,它们有什么区别?

简单来说,-c(crown-margin)使段落第一行顶格,后续行缩进;-t(tagged-paragraph)则相反:第一行缩进,后续行顶格。具体使用哪个,取决于你文本原本的缩进结构。

如果段落是首行缩进两格、其余顶格,就用 -t;如果段落是首行顶格、第二行起缩进,就用 -c。如果两个参数都不生效,大概率是原始缩进使用了制表符,而 fmt 默认按空格计算宽度。可以先添加 -u 参数将全部空格统一,再试一次。

管道输入时,格式化结果突然变窄或错位

通过管道传入的数据没有文件元信息,fmt 容易误判段落边界。最典型的场景是:一条长命令的输出被切成了碎片,或者换行位置显得特别诡异。

要避免这个问题,首先要确保输入是纯文本段落,没有混入 ANSI 转义序列——例如 ls --color 的输出不能直接喂给 fmt,先通过 cat -v 检查一下。如果用 echo 测试,记得加引号:echo "long line" | fmt -w 40。不加引号的话,shell 会先按空格将内容切碎再传给 fmt,结果自然不对。如果希望保留原始换行逻辑,可以尝试 -d 选项,但请注意该选项并非所有发行版都支持——Ubuntu 22.04 以上版本支持,CentOS 7 默认没有。

总而言之,fmt 的段落识别完全依赖空行和行首空白,它不解析语义。即便你给它一篇 Markdown 文档,它也只当作普通文本处理。要想安全地格式化,正确的做法是先剥离标记、统一缩进,再将处理后的内容喂给 fmt。这活儿看起来简单,细节上却有不少坑。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›