fmt 默认按空行分隔段落并重排,若输出成一行说明源文本无空行;处理注释需严格匹配前缀且无前置空格;-c 和 -t 控制首行缩进逻辑;管道输入需避免控制字符干扰。

fmt 默认就做这件事:读取段落、合并短行、折行长行、保持空行分隔——不用额外参数,它就能把杂乱文本变成可读的均匀段落。
直接格式化文件时为什么输出乱成一行?
这不是 bug,是 fmt 的默认行为:它把每个逻辑段落(用空行分隔)压缩成单行再重排。如果你看到「所有内容挤在一行」,说明原始文本里没有空行,fmt 就当它是同一段处理了。
- 检查源文件是否真有段落分隔:用
cat -A file.txt看有没有^M或空白行 - 想强制按物理行切分?加
-s(只拆不分)+-w,比如fmt -s -w 60 file.txt - 原始文本含制表符或混合空格缩进?
fmt可能误判段落边界,先用sed 's/^[[:space:]]*//'清理首空格
处理代码注释时 -p 选项总丢前缀?
-p 要求前缀**严格匹配行首**,且格式化后会自动重加该前缀——但前提是整行都以它开头(不能有空格)。常见失败点:
- 注释写成
# long comment(前面有空格)→fmt -p '# '不生效,得先sed 's/^ *#/#/' - 前缀带空格,如
#,必须写成-p '# ',少一个空格或引号不闭合都会报错fmt: invalid option -- 'p' - 多行注释混用
#和//?fmt一次只能处理一种前缀,需分两次调用
-c 和 -t 都说保留缩进,区别在哪?
-c(crown-margin)让段落第一行顶格,后续行缩进;-t(tagged-paragraph)则相反:第一行缩进,后续行顶格。实际效果取决于你文本原本的缩进结构:
- 如果段落是「首行缩进两格,其余顶格」→ 用
-t - 如果段落是「首行顶格,第二行起缩进」→ 用
-c - 两者都不生效?可能原始缩进是制表符,而
fmt默认按空格计算宽度,加-u统一空格后再试
管道输入时格式化结果突然变窄或错位
从管道进来的数据没有文件元信息,fmt 容易误判段落边界。典型现象:长命令输出被切成碎片,或换行位置诡异。
- 确保输入是纯文本段落,避免混入 ANSI 转义序列(如
ls --color输出),先过一遍cat -v检查 - 用
echo测试时,记得加引号:echo "long line" | fmt -w 40,否则 shell 会先按空格切分再传给fmt - 想保留原始换行逻辑?加
-d(但注意:该选项不是所有发行版都支持,Ubuntu 22.04+ 有,CentOS 7 默认无)
fmt 的段落识别完全依赖空行和行首空白,不解析语义。哪怕你给它一篇 Markdown,它也只当普通文本处理——真正要安全格式化,得先剥离标记、统一缩进、再喂给 fmt。











