fmt命令是一个简单的文本格式化工具,主要用于重新格式化文本文件中的段落。它可以调整文本的换行位置,使每行具有大致相同的长度,并保持段落的完整性。fmt特别适合处理纯文本文件、电子邮件和文档。
fmt [选项] [文件...]
| 选项 | 说明 |
|---|---|
| -w width | 设置输出行的最大宽度(默认75字符) |
| -s | 只分割长行,不合并短行 |
| -u | 统一空格:单词间一个空格,句子间两个空格 |
| -t | 缩进第一行比对第二行多两个空格 |
| -c | 保留段落的起始缩进 |
| -p prefix | 只格式化以指定前缀开头的行 |
| --goal=width | 设置目标宽度(尽量接近但不超出的宽度) |
| --split-only | 同-s选项 |
| --tagged-paragraph | 同-t选项 |
| --crown-margin | 同-c选项 |
| --uniform-spacing | 同-u选项 |
| --help | 显示帮助信息 |
| --version | 显示版本信息 |
fmt命令通过以下步骤格式化文本:
格式化文本文件为指定宽度:
# 创建测试文件
cat > unformatted.txt << 'EOF'
这是一个很长的段落,包含很多文字。
这个段落需要被格式化,使得每行都有合适的长度。
这样阅读起来会更加舒适和美观。
格式化后的文本应该具有一致的宽度。
这是另一个段落,同样需要格式化处理。
段落之间应该保持空行分隔。
EOF
# 基本格式化(默认75字符宽度)
fmt unformatted.txt
# 指定40字符宽度
fmt -w 40 unformatted.txt
# 保存格式化结果
fmt -w 50 unformatted.txt > formatted.txt
格式化时保留段落的起始缩进:
# 创建带缩进的文本
cat > indented.txt << 'EOF'
这是一个缩进的段落。
这个段落有多行文字,每行前面都有空格。
格式化时应该保留这个缩进。
这是另一个缩进段落。
同样需要保留缩进格式。
EOF
# 使用-c选项保留缩进
fmt -c -w 50 indented.txt
# 比较不使用-c选项的效果
fmt -w 50 indented.txt
使用-s选项只分割长行而不合并短行:
# 创建混合长短行的文件
cat > mixed.txt << 'EOF'
短行。
这是一个非常长的行,需要被分割成多行以便于阅读和显示。
短行。
另一个很长的行,也需要被适当地分割处理。
EOF
# 只分割长行,不合并短行
fmt -s -w 40 mixed.txt
# 比较默认行为(合并短行)
fmt -w 40 mixed.txt
使用-u选项统一空格:
# 创建包含不规则空格的文本
cat > spaces.txt << 'EOF'
这个 句子 有 很多 不规则 空格。
另一个 句子。也有很多 多余空格。
格式化 后 应该 统一 空格。
EOF
# 统一空格:单词间一个空格,句子间两个空格
fmt -u -w 50 spaces.txt
使用-p选项只格式化以特定前缀开头的行:
# 创建包含注释和代码的混合文件
cat > code_with_comments.txt << 'EOF'
# 这是一个很长的注释行,需要被格式化以便更好地阅读和理解代码的功能和实现方式
def function_name():
# 另一个长注释,描述函数的具体行为和参数
print("Hello World")
# 主程序入口点
if __name__ == "__main__":
function_name()
EOF
# 只格式化注释行(以#开头的行)
fmt -p '#' -w 40 code_with_comments.txt
通过管道处理其他命令的输出:
# 从echo命令获取输入
echo "这是一个很长的句子,需要通过fmt命令进行格式化处理以适合显示宽度。" | fmt -w 30
# 处理文件内容
cat long_text.txt | fmt -w 60
# 结合其他文本处理命令
grep "important" document.txt | fmt -w 50 | head -10
自动格式化文本文档和电子邮件:
#!/bin/bash
# 格式化文本邮件
format_email() {
local input_file=$1
local output_file=$2
local width=${3:-72}
echo "格式化邮件: $input_file → $output_file (宽度: $width)"
# 格式化邮件正文
fmt -u -w "$width" "$input_file" > "$output_file"
# 添加邮件头
sed -i "1i\\
$(date)\\
收件人: recipient@example.com\\
发件人: sender@example.com\\
主题: 格式化后的邮件\\
\\
" "$output_file"
echo "邮件格式化完成"
}
# 创建示例邮件内容
cat > draft_email.txt << 'EOF'
尊敬的收件人:
这封邮件包含一些很长的段落,需要被适当地格式化以便于阅读。fmt命令可以帮助我们自动完成这个任务,使得每行都有合适的长度。
希望这个示例对您有所帮助。
此致
敬礼
EOF
# 使用函数
format_email "draft_email.txt" "formatted_email.txt" 65
统一格式化源代码中的注释:
#!/bin/bash
# 格式化源代码注释
format_code_comments() {
local source_file=$1
local backup_file="${source_file}.backup"
local comment_width=60
echo "格式化代码注释: $source_file"
# 创建备份
cp "$source_file" "$backup_file"
# 处理不同语言的注释
if [[ "$source_file" == *.py ]]; then
# Python文件:处理#注释
fmt -p '#' -w "$comment_width" "$source_file" > "${source_file}.tmp"
elif [[ "$source_file" == *.java ]] || [[ "$source_file" == *.c ]] || [[ "$source_file" == *.cpp ]]; then
# Java/C/C++文件:处理//注释
fmt -p '//' -w "$comment_width" "$source_file" > "${source_file}.tmp"
elif [[ "$source_file" == *.sql ]]; then
# SQL文件:处理--注释
fmt -p '--' -w "$comment_width" "$source_file" > "${source_file}.tmp"
else
echo "不支持的文件类型: $source_file"
return 1
fi
mv "${source_file}.tmp" "$source_file"
echo "注释格式化完成,原文件备份为: $backup_file"
}
# 创建示例Python文件
cat > example.py << 'EOF'
# 这是一个很长的注释,描述这个函数的功能和用途,需要被格式化以便更好地阅读和理解
def calculate_sum(a, b):
# 这个注释也很长,描述参数a和b的含义以及函数的返回值类型和可能的异常情况
return a + b
# 主函数入口点,包含程序的主要逻辑和执行流程
if __name__ == "__main__":
result = calculate_sum(5, 3)
print(f"结果是: {result}")
EOF
# 使用函数
format_code_comments "example.py"
cat example.py
整理和格式化配置文件:
#!/bin/bash
# 整理配置文件格式
format_config_file() {
local config_file=$1
local formatted_file="${config_file}.formatted"
echo "整理配置文件: $config_file"
# 分别处理注释和配置项
{
# 处理注释(以#开头的行)
grep "^#" "$config_file" | fmt -p '#' -w 70
echo
# 处理配置项(不以#开头的非空行)
grep -v "^#" "$config_file" | grep -v "^$" | fmt -w 70
} > "$formatted_file"
echo "配置文件整理完成: $formatted_file"
echo "=== 格式化前后对比 ==="
echo "原文件行数: $(wc -l < "$config_file")"
echo "新文件行数: $(wc -l < "$formatted_file")"
}
# 创建杂乱的配置文件
cat > messy_config.conf << 'EOF'
# 数据库配置部分,包含连接信息和认证凭据
db.host=localhost
db.port=5432 # 数据库端口号
db.name=myapp
# 应用服务器配置
server.port=8080
server.host=0.0.0.0
# 日志配置
log.level=INFO
log.file=/var/log/myapp.log
EOF
# 使用函数
format_config_file "messy_config.conf"
cat messy_config.conf.formatted
将fmt与sed结合使用:
# 先使用sed预处理,再用fmt格式化
sed 's/ \+/ /g' text.txt | fmt -w 60
# 格式化后添加行号
fmt -w 50 text.txt | nl -ba
# 处理特定段落
sed -n '/开始段落/,/结束段落/p' document.txt | fmt -w 40
处理包含中文等宽字符的文本:
# 创建中英文混合文本
cat > mixed_lang.txt << 'EOF'
这是一个包含中文和英文的混合文本段落。
This paragraph contains both Chinese and English text.
中英文混合时需要注意字符宽度的计算。
The fmt command handles this reasonably well.
EOF
# 格式化混合语言文本
fmt -w 40 mixed_lang.txt
# 对于精确的宽度控制,可能需要专门工具
# 或者手动调整宽度值
使用循环批量格式化多个文件:
#!/bin/bash
# 批量格式化文本文件
batch_format_files() {
local directory=$1
local width=${2:-70}
echo "批量格式化目录: $directory"
echo "目标宽度: $width"
# 查找所有文本文件
find "$directory" -name "*.txt" -o -name "*.md" -o -name "*.rst" | while read file; do
echo "处理: $file"
# 创建格式化版本
fmt -u -w "$width" "$file" > "${file}.fmt"
# 可选:替换原文件
# mv "${file}.fmt" "$file"
done
echo "批量格式化完成"
}
# 使用函数
# batch_format_files "./documents" 65
使用-c选项保留段落缩进:
# 保留缩进格式化
fmt -c -w 60 file.txt
# 或者使用-s选项只分割不合并
fmt -s -w 60 file.txt
# 对于代码等需要精确空格的文本,考虑使用其他工具
# 或者手动处理特定部分
调整宽度值或使用专门的中文处理工具:
# 对于中文文本,适当减少宽度值
fmt -w 40 chinese_text.txt
# 使用其他支持Unicode宽度计算的工具
# 或者使用文本编辑器的格式化功能
# 手动调整后处理
fmt -w 50 text.txt | sed 's/ *$//' # 移除行尾空格
结合其他工具选择要格式化的内容:
# 只格式化注释
fmt -p '#' -w 60 source.py
# 格式化特定标记之间的内容
sed -n '/BEGIN_FORMAT/,/END_FORMAT/p' file.txt | fmt -w 50
# 使用awk选择特定行
awk '/^[A-Z]/ {print}' file.txt | fmt -w 40
| 命令 | 说明 | 区别 |
|---|---|---|
| fold | 折叠长行 | 简单地在指定位置换行,不重新组织文本 |
| pr | 格式化文本文件以便打印 | 添加页眉、页脚和多列布局 |
| par | 段落格式化工具 | 更强大的段落格式化,支持更多选项 |
| col | 过滤反向换行符 | 处理控制字符,不是文本格式化 |
| nl | 添加行号 | 给文本添加行号,不改变内容格式 |
| sed | 流编辑器 | 可以进行复杂的文本转换 |
| awk | 文本处理语言 | 适合复杂的文本处理和数据提取 |
fmt命令最适合处理纯文本段落,如邮件正文、文档内容和注释。对于需要精确格式的文本(如代码、表格),建议使用专门的格式化工具或文本编辑器的格式化功能。在处理重要文件前,始终先备份原文件或测试格式化效果。