Shell printf 命令

《Shell printf 命令》

🎯 学习目标

  • 理解 printf 的作用和与 echo 的区别
  • 掌握各种格式说明符(format specifiers)及其用法
  • 能够实现对齐、填充、精度控制等高级文本格式化
  • 在实际脚本中应用 printf 构建结构化日志、表格、报告等
  • 避免常见陷阱,写出健壮可靠的 Shell 输出语句

⭐ 核心重点(知识点速览)

类别 内容 示例
基本语法 printf format [arguments...] printf "Name: %s\n" "Tom"
字符串格式化 %s printf "%s\n" "Hello"
整数格式化 %d, %i printf "Age: %d\n" 25
浮点数格式化 %f, %.nf printf "%.2f\n" 3.14159
字段宽度控制 %N$s, %Nd, %Nf printf "%10s\n" "Right"
左右对齐 %-Ns(左)、默认右对齐 `printf "%-10s
填充字符 0 表示数字前补零 printf "%05d\n" 700007
进制转换 %x, %X, %o printf "%x\n" 255ff
转义字符 \n, \t, \\ printf "Line1\\nLine2\n"
颜色支持 结合 ANSI 编码 printf "\033[31mError\033[0m\n"

📖 详细讲解


一、为什么选择 printf

虽然 echo 是最常用的输出命令,但它在格式控制方面非常有限。例如:

echo "User: Tom, Age: 25"

输出:

User: Tom, Age: 25

但如果你希望对齐多个用户的输出,或者控制小数点位数、补零、进制转换等,echo 就显得力不从心了。

printf 提供了类似 C 语言 printf() 函数的强大功能,是 Shell 脚本中进行格式化输出的最佳选择!


二、基本语法格式

printf format-string [argument ...]
  • format-string:格式字符串,包含普通字符和格式说明符(以 % 开头)
  • [argument ...]:要插入到格式字符串中的变量或值

✅ 示例:

name="Alice"
age=28
printf "姓名:%s,年龄:%d\n" "$name" "$age"

输出:

姓名:Alice,年龄:28

三、常用格式说明符(Format Specifiers)

占位符 含义 示例
%s 字符串 "Tom"
%d%i 有符号十进制整数 25
%u 无符号整数(某些系统支持) 100
%f 浮点数 3.14159
%.nf 控制小数点后 n 位 %.2f → 3.14
%e / %E 科学计数法 3.14159e+00
%g / %G 自动选择 %f%e 3.14159
%c 单个字符 'A'
%b 处理转义序列(如 \n "Line1\\nLine2"
%x / %X 十六进制(小写/大写) ff / FF
%o 八进制 377

四、格式修饰符(Modifier)

你可以在格式符前添加修饰符,进一步控制输出样式:

1️⃣ 宽度控制(Field Width)

printf "%10s\n" "Right"    # 右对齐,总宽10
printf "%-10s\n" "Left"    # 左对齐,总宽10

输出:

     Right
Left     

2️⃣ 填充字符(Padding)

默认填充空格,加 0 表示用 0 填充:

printf "%05d\n" 7

输出:

00007

3️⃣ 精度控制(Precision)

适用于浮点数和字符串:

printf "%.2f\n" 3.1415926   # 保留两位小数
printf "%.5s\n" "abcdefg"   # 只取前5个字符

输出:

3.14
abcde

4️⃣ 参数编号(Positional Arguments)

你可以通过 $ 显式指定参数位置,避免顺序错误:

printf "%2\$s is %1\$d years old.\n" 28 "Alice"

输出:

Alice is 28 years old.

五、进制转换与数值处理

✅ 十进制转十六进制

printf "Hex: %x\n" 255

输出:

Hex: ff

✅ 十进制转八进制

printf "Octal: %o\n" 64

输出:

Octal: 100

✅ 十六进制转十进制

hex="FF"
printf "Decimal: %d\n" "0x$hex"

输出:

Decimal: 255

六、结合 ANSI 颜色代码输出彩色内容

RED='\033[31m'
GREEN='\033[32m'
NC='\033[0m'

printf "${RED}ERROR:${NC} 文件未找到\n"
printf "${GREEN}SUCCESS:${NC} 数据已导入\n"

输出效果:
🔴 ERROR:文件未找到
🟢 SUCCESS:数据已导入


七、实用案例讲解

🧪 案例 1:生成整齐的用户信息表

printf "| %-10s | %3s | %15s |\n" "Name" "Age" "Email"
printf "| %-10s | %3s | %15s |\n" "----------" "---" "---------------"
printf "| %-10s | %3d | %15s |\n" "Alice" 28 "alice@example.com"
printf "| %-10s | %3d | %15s |\n" "Bob" 30 "bob@example.com"

输出:

| Name       | Age |           Email |
| ---------- | --- | --------------- |
| Alice      |  28 | alice@example.com |
| Bob        |  30 | bob@example.com     |

💡 这种格式非常适合用于生成日志、报表、配置文件等。


🧪 案例 2:显示进度条模拟器

for i in {1..100..10}; do
    printf "\rProgress: [%-10s] %d%%" $(printf '=%.0s' $(seq 1 $((i/10)))) "$i"
    sleep 0.2
done
printf "\n"

输出效果:

Progress: [==========] 100%

💡 使用 \r 实现覆盖当前行,适合做简单的进度提示。


🧪 案例 3:格式化时间戳输出

timestamp=$(date +%s)
formatted=$(date -d "@$timestamp" "+%Y-%m-%d %T")
printf "当前时间:%s\n" "$formatted"

输出:

当前时间:2025-06-18 09:15:23

⚠️ 注意事项 & 常见坑

问题 原因 解决方法
不换行 忘记加 \n 添加 \n
参数不匹配 格式符数量 ≠ 参数数 检查参数顺序和数量
数字变成乱码 使用 %s 打印数字 改为 %d%f
补零失败 忘记加 0 修饰符 %05d
输出中文乱码 终端编码不一致 设置 export LANG=en_US.UTF-8
颜色未生效 忘记加 -e 或未重置 使用 echo -eprintf 自带支持

🧠 总结 & 小贴士

技巧 说明
printf 更灵活 相比 echo,能精确控制格式
支持多种格式符 %s, %d, %f, %x, %o
对齐和补零 %10s, %-10s, %05d
支持 ANSI 颜色 可美化输出界面
支持参数编号 %2$s 等可提升脚本可读性
适合生成表格 对齐排版利器
建议封装函数 log_info(), log_error()

📚 推荐练习题(可选)

  1. 编写一个脚本,输出所有用户的用户名、UID 和家目录,按列对齐。
  2. 使用 printf 生成一个 1~10 的乘法表。
  3. 编写一个带颜色的日志函数 log_info, log_warn, log_error
  4. 输出磁盘使用情况表格(挂载点、总容量、已用、可用、使用率)。
  5. 实现一个简单的进度条动画,使用 printfsleep

🎯 下一章预告:《Shell read 命令与用户交互》

你已经掌握了如何输出格式化的内容,下一步我们将学习如何接收用户输入 —— 使用强大的 read 命令,让脚本更具互动性和灵活性!

需要我继续为你生成下一章内容吗?😊

posted @ 2023-04-02 21:34  红尘过客2022  阅读(46)  评论(0)    收藏  举报