Shell printf 命令

Shell printf 命令详解(新手详细版)

本文档面向零基础新手,从“printf 是干什么的、和 echo 有什么不同”讲起,详细说明语法、格式符、宽度与精度、转义、多参数与复用、实用示例等,并配有大量示例。


一、printf 是什么?

1.1 一句话理解

printf 用来按格式把内容输出到标准输出:你可以指定“占位符”(如 %s 字符串、%d 整数、%f 小数),再按顺序把变量或值填进去,还能控制宽度、对齐、小数位数等。
和 C 语言里的 printf 用法类似。

  • 不自动换行:想换行必须在格式里写 n
  • 格式 + 参数:第一个参数是“格式字符串”,后面是填进格式里的各个值。
  • 可移植性好:POSIX 标准,各系统行为一致;转义 nt 等默认就解释,不像 echo 要 -e。

1.2 和 echo 的简单对比

特性 echo printf
末尾换行 默认有 没有,需自己写 n
转义 n t 需 echo -e(Bash) 默认解释
格式控制 有 %s、%d、%f、宽度等
可移植性 -e、-n 不统一 POSIX,统一

需要对齐、小数位、不换行、可移植时,用 printf 更合适。


二、基本语法

printf 格式字符串 [参数1 参数2 ...]
  • 格式字符串:由普通字符和格式说明符(以 % 开头)组成;% 后面跟的字母表示“这里用哪种类型、怎么显示”。
  • 参数:按顺序依次填进格式说明符;若参数比说明符多,格式串会被重复使用;若少,多出来的 % 会得到空或 0。

示例:

printf "你好,%sn" "张三"
# 你好,张三
# (n 带来换行)

printf "数字: %dn" 42
# 数字: 42

三、格式说明符(占位符)

3.1 常用说明符

说明符 含义 示例
%s 字符串 printf "%s" "hello"
%d%i 有符号整数(十进制) printf "%d" 100
%u 无符号整数 printf "%u" 100
%f 浮点数(小数) printf "%f" 3.14
%e%E 科学计数法 printf "%e" 1000 → 1.000000e+03
%g%G 自动选 %f 或 %e,去掉多余 0 printf "%g" 3.14
%x%X 十六进制(小写/大写) printf "%x" 255 → ff
%o 八进制 printf "%o" 8 → 10
%c 单个字符 printf "%c" 65 → A
%% 字面百分号 % printf "完成度 50%%n"

3.2 宽度与对齐(以 %s、%d 为例)

% 和字母之间可以写数字

  • %数字s:最少占“数字”个字符宽度,不足右侧补空格(右对齐)。
  • %-数字s:最少占“数字”个字符宽度,不足左侧补空格(左对齐)。
printf "%10sn" "hi"
#         hi(前面 8 个空格,总宽 10)

printf "%-10s endn" "hi"
# hi         end(hi 后面 8 个空格)

printf "%5dn" 42
#    42(前面 3 个空格)

3.3 小数精度:%.位数f

%.2f 表示保留两位小数%8.2f 表示总宽 8、其中小数 2 位。

printf "%.2fn" 3.14159
# 3.14

printf "%8.2fn" 3.14159
#     3.14(总宽 8,右对齐)

3.4 格式小结(常用写法)

写法 含义
%s 字符串
%5s 至少 5 个字符宽,右对齐
%-5s 至少 5 个字符宽,左对齐
%d、%i 整数
%5d 至少 5 位数字,右对齐
%f 浮点数(默认约 6 位小数)
%.2f 保留 2 位小数
%10.2f 总宽 10,2 位小数
%% 一个 % 字面

四、转义序列(默认就解释)

在格式字符串里,以下反斜杠会被解释(不需要像 echo 那样加 -e):

写法 含义
n 换行
t 制表符(Tab)
r 回车
一个反斜杠
�nnn 八进制 nnn 对应字符
xHH 十六进制 HH 对应字符
printf "第一行n第二行n"
# 第一行
# 第二行

printf "姓名t年龄n张三t25n"
# 姓名    年龄
# 张三    25

五、不自动换行:必须自己写 n

printf 不会在最后自动加换行,所以格式里要显式写 n,否则下一次输出会接在同一行后面:

printf "hello"
printf "world"
# helloworld(同一行)

printf "hellon"
printf "worldn"
# hello
# world

六、参数与格式的对应关系

6.1 按顺序一一对应

格式里的第一个 %第一个参数第二个 %第二个参数,依此类推:

printf "%s 今年 %d 岁n" "李四" 20
# 李四 今年 20 岁

6.2 参数多于格式说明符:格式会重复用

若参数比格式里的 % 多,printf 会再次使用整个格式串,继续消耗剩余参数:

printf "%sn" a b c
# a
# b
# c

每次用格式 “%sn” 消耗一个参数,所以 a、b、c 各占一行。

6.3 参数少于格式说明符:多出来的 % 行为未定义

% 比参数多,多出来的 % 会得到“未定义”的值(可能是空、0 或乱码),应避免这种情况。

6.4 指定第几个参数(POSIX 未要求,部分 Shell)

部分 Shell 支持 %2$s 表示“用第 2 个参数”;可移植脚本慎用,这里不展开。


七、实用示例

7.1 简单字符串 + 换行

printf "程序开始n"
printf "当前用户: %sn" "$USER"

7.2 对齐表格(左对齐、右对齐)

printf "%-10s %5sn" "姓名" "分数"
printf "%-10s %5dn" "张三" 90
printf "%-10s %5dn" "李四" 85
# 姓名         分数
# 张三           90
# 李四           85

7.3 保留小数位

printf "价格: %.2f 元n" 19.5
# 价格: 19.50 元

printf "比例: %.1f%%n" 66.78
# 比例: 66.8%

7.4 不换行(提示后读入)

printf "请输入文件名: "
read -r file

7.5 十六进制、八进制

printf "255 的十六进制: %xn" 255
# 255 的十六进制: ff
printf "8 的八进制: %on" 8
# 8 的八进制: 10

7.6 多个值一行一个(格式复用)

printf "%sn" 苹果 香蕉 橙子
# 苹果
# 香蕉
# 橙子

7.7 输出到文件或 stderr

printf 的标准输出可以重定向,和 echo 一样:

printf "错误: 文件不存在n" >&2
printf "日志内容n" >> app.log

八、与变量、命令替换配合

8.1 变量作参数

变量放在格式串后面作参数即可;建议变量加双引号,避免空或含空格出错:

name="王五"
age=30
printf "姓名: %s, 年龄: %dn" "$name" "$age"

8.2 命令替换作参数

$(命令) 的输出会作为字符串传给 printf:

printf "行数: %sn" "$(wc -l < file.txt)"
printf "今天: %sn" "$(date +%Y-%m-%d)"

九、常见坑与建议

  1. 忘记写 n:printf 不自动换行,格式末尾要加 n,否则下次输出接在同一行。
  2. 宽度与中文%10s字节算宽度,中文等多字节字符可能对不齐;若需对齐可用专门工具或固定用英文/数字。
  3. 参数类型要匹配%d 对应整数,%s 对应字符串;给错类型可能得到奇怪结果。
  4. 变量加引号“$var”,避免空或含空格时参数错位。
  5. %% 输出百分号:格式里要输出字面 % 必须写 %%

十、格式说明符速查表

说明符 含义
%s 字符串
%d、%i 有符号整数
%u 无符号整数
%f 浮点数
%e、%E 科学计数法
%g、%G 自动选 f 或 e
%x、%X 十六进制
%o 八进制
%c 单字符
%% 字面 %
%5s、%-5s 宽 5,右/左对齐
%.2f、%8.2f 2 位小数,总宽 8

十一、与 echo 的选用建议

  • 简单一行、提示、调试:用 echo 即可。
  • 不换行printf “xxx”echo -n 可移植。
  • 多行、n tprintf 默认解释转义,比 echo -e 可移植。
  • 对齐、小数位、十六进制等:只能用 printf
  • 写脚本希望各系统都能跑:优先 printf

十二、小结

  • printf格式字符串 + 参数输出;不自动换行,需在格式里写 n
  • 格式说明符%s 字符串、%d 整数、%f 小数、%% 百分号;%5s%-5s 控制宽度与对齐;%.2f%8.2f 控制小数位和总宽。
  • 转义nt 等默认解释;参数按顺序对应 %,多出的参数会重复使用格式。
  • 需要对齐、小数、可移植、不换行时用 printf;简单输出用 echo 即可。

多练:对齐表格、保留小数、不换行提示、多参数、重定向,再结合 Shell echo 命令.mdShell变量.md 一起用,printf 就能用熟。


文档以 POSIX printf 为准;部分 Shell 扩展(如 %b、%q)未涉及。

发表评论