printf 命令是 C 语言中 printf() 函数的命令行版本,它是一个强大的工具,用于格式化并输出文本,与 echo 命令相比,printf 提供了更精确、更灵活的控制,尤其是在处理数字、对齐文本和格式化输出时。

基本语法
printf 的基本语法非常简单:
printf [选项] 格式字符串 [参数1] [参数2] ...
- 选项:最常用的选项是
-v varname,它将格式化后的结果赋值给变量varname,而不是直接输出到标准输出。 - 格式字符串:这是
printf的核心,它包含两种类型的字符:- 普通字符:原样输出。
- 格式说明符:以 开头,用于定义后续参数的输出格式。
- 参数:要格式化的数据,参数的数量必须与格式字符串中格式说明符的数量匹配。
格式说明符
格式说明符是 printf 的精髓,它的通用形式是:
%[标志][宽度][.精度]类型
下面我们逐一分解这些部分。
1 类型
类型指定了如何解释对应的参数(是作为整数、浮点数还是字符串)。

| 类型 | 说明 | 示例 |
|---|---|---|
d, i |
十进制有符号整数。 | printf "%d\n" 123 |
u |
十进制无符号整数。 | printf "%u\n" -1 (会得到一个很大的数) |
f |
浮点数(双精度)。 | printf "%.2f\n" 3.14159 |
e, E |
科学计数法(e/E 表示指数)。 | printf "%e\n" 1000 (输出 000000e+03) |
g, G |
自动选择 %f 或 %e 中更紧凑的形式。 |
printf "%g\n" 1000.0 (输出 1000) |
s |
字符串。 | printf "%s\n" "hello" |
c |
字符(ASCII 码)。 | printf "%c\n" 65 (输出 A) |
b |
将参数作为二进制数输出(非标准,但 Bash 内置支持)。 | printf "%b\n" "A" (输出 01000001) |
| 输出一个百分号 本身。 | printf "%%\n" |
2 宽度
指定输出字段的最小宽度,如果内容宽度小于此值,则用空格填充(默认右对齐)。
printf "%10s\n" "hello" # 输出 " hello" (hello 右对齐,总宽度为10) printf "%-10s\n" "hello" # 输出 "hello " (hello 左对齐,总宽度为10)
3 精度
对于浮点数(f, e, g),它指定小数点后的位数。
对于字符串(s),它指定输出的最大字符数。
printf "%.3f\n" 3.1415926 # 输出 "3.142" (四舍五入到3位小数) printf "%.5s\n" "helloworld" # 输出 "hello" (只输出前5个字符)
4 标志
标志是加在 和其他格式说明符之间的修饰符,用于改变输出方式。
| 标志 | 说明 | 示例 |
|---|---|---|
| 左对齐(默认是右对齐)。 | printf "%-5d\n" 123 (输出 123) |
|
| 对于数字,总是显示正负号( 或 )。 | printf "%+d\n" 123 (输出 +123) |
|
| ` ` (空格) | 对于正数,在前面留一个空格代替 号。 | printf "% d\n" 123 (输出 123) |
0 |
用前导零填充数字,而不是空格。 | printf "%05d\n" 123 (输出 00123) |
"替代格式",对于 o(八进制),前面加 0;对于 x 或 X(十六进制),前面加 0x 或 0X。 |
printf "%#x\n" 255 (输出 0xff) |
|
| 对于浮点数,按千位分隔符(逗号)格式化数字(GNU 扩展)。 | printf "%'.2f\n" 1234567.89 (输出 1,234,567.89) |
实用示例
示例 1:基本格式化输出
# 输出字符串和数字 name="Alice" age=30 printf "Name: %s, Age: %d\n" "$name" $age # 输出: Name: Alice, Age: 30
注意:如果参数可能包含空格或特殊字符,最好用双引号 括起来,"$name"。
示例 2:数字格式化(宽度、精度、对齐)
# 右对齐,宽度10,小数点后2位 printf "Price: %10.2f\n" 1234.5 # 输出: Price: 1234.50 # 左对齐,宽度10,小数点后2位 printf "Price: %-10.2f\n" 1234.5 # 输出: Price: 1234.50
示例 3:使用标志
# 显示正负号 printf "%+d, %+d\n" 10 -10 # 输出: +10, -10 # 用前导零填充 printf "ID: %05d\n" 42 # 输出: ID: 00042 # 显示十六进制替代格式 printf "Hex: %#x\n" 255 # 输出: Hex: 0xff
示例 4:处理多个参数
printf 会循环使用格式字符串,直到所有参数都处理完毕。
# 格式字符串 "%s %d" 会被循环使用 printf "%s %d\n" "apple" 1 "banana" 2 "cherry" 3 # 输出: # apple 1 # banana 2 # cherry 3
如果参数比格式说明符多,多余的格式说明符会被忽略。 如果格式说明符比参数多,多余的说明符会以 的形式输出。
# 参数不足 printf "%s %d %s\n" "one" 2 # 输出: one 2 % # 格式说明符不足 printf "%s\n" "a" "b" "c" # 输出: # a # b # c
示例 5:将结果赋值给变量
使用 -v 选项可以将格式化后的字符串存入一个变量,这在脚本中非常有用。
version="1.2.3" printf -v formatted_version "Version: %s" "$version" echo $formatted_version # 输出: Version: 1.2.3
示例 6:创建格式化表格
这是 printf 的一个经典应用场景。
# 定义数据 name1="Zhang San" score1=95 name2="Li Si" score2=88 name3="Wang Wu" score3=76 # 使用 printf 输出格式化的表头和内容 # %-15s 表示左对齐,最小宽度15 # %5d 表示右对齐,最小宽度5 printf "%-15s %5s\n" "Name" "Score" printf "%-15s %5d\n" "$name1" $score1 printf "%-15s %5d\n" "$name2" $score2 printf "%-15s %5d\n" "$name3" $score3
输出结果:
Name Score
Zhang San 95
Li Si 88
Wang Wu 76
printf vs echo
| 特性 | printf |
echo |
|---|---|---|
| 标准 | 遵循 C 语言标准,行为可预测。 | 行为因 Shell 而异(如 Bash, Dash, Zsh),不标准。 |
| 功能 | 强大的格式化能力。 | 功能简单,主要用于简单输出。 |
| 参数处理 | 严格按格式说明符处理参数。 | 通常将所有参数用空格连接后输出。 |
| 转义字符 | \n, \t 等转义字符在双引号内才有效。 |
-e 选项启用转义,但不同 Shell 支持的转义序列可能不同。 |
| 默认换行 | 不自动添加换行符,必须手动添加 \n。 |
通常自动添加换行符(除非使用 -n 选项)。 |
当您需要精确控制输出格式、对齐方式、数字精度时,请始终使用 printf,对于简单的、不需要格式化的输出,echo 更为简洁。
特殊说明:Bash 内置 printf
在大多数现代 Linux 发行版中,/usr/bin/printf 是一个独立的 GNU printf 程序,Bash Shell 本身也内置了一个 printf 命令。
- Bash 内置
printf:通常比外部程序更快,并且有一些细微差别(例如对\uUnicode 转义序列的支持)。 - 外部
printf:行为严格遵循 POSIX 标准。
在绝大多数情况下,两者的行为是一致的,您可以通过 type printf 命令来查看当前 Shell 使用的是哪个 printf。
$ type printf printf is a shell builtin # 如果是内置的
或者
$ type printf printf is /usr/bin/printf # 如果是外部的
