printf 是什么
printf 是格式化输出工具,bash 内有同名内建,系统里通常也有 /usr/bin/printf。它比 echo 可控:不会因为不同 shell 或发行版对 -e、反斜杠转义的处理差异而改变行为,能精确控制宽度对齐、补零、进制转换和 shell 转义。脚本里生成定宽表格、批量编号文件名、带百分比的进度输出,用 printf 比拼接 echo 稳得多,同一格式串在不同机器上结果一致。
基本信息
| 适用平台 | GNU/Linux、macOS(bash 内建与 coreutils 版本) |
|---|---|
| 语法 | printf 格式串 [参数...] |
| 常用转换符 | %s 字符串 %d 整数 %q shell 转义 %02d 两位补零 %-16s 左对齐定宽 |
| 常用转义 | \n 换行 \t 制表 %% 字面百分号 \r 回车 |
| 参数不足 | bash 内建按格式串循环复用,缺的位置补 0 或空串 |
| 输出目标 | 默认写到标准输出,重定向即可生成文件 |
典型使用场景
- 生成对齐的报表行:用固定宽度把主机名、状态、耗时排成整齐两列三列。
- 批量构造定宽编号或文件名,如生成 01、02 到 12 的序列名。
- 把可能含空格、分号的值转成能安全回填 shell 的形式(%q),避免二次解析出错。
- 打印带百分比的进度信息,配合回车在同一行刷新。
- 写脚本日志时精确控制换行与制表符,不依赖 echo -e 的实现差异。
常用写法
常用写法
printf '%-16s %s\n' host01 online host02 offline # 按两列对齐输出
printf '%02d\n' $(seq 1 5) # 输出 01 到 05
printf '%q\n' 'a b;c' # 输出可安全复用的 shell 形式
printf '进度: %d%%\r' 42 # 百分号要写 %%,\r 原地刷新
printf '%s\t%s\n' "$name" "$size" # 制表符分隔,便于后续 awk 处理
printf '%d\n' 0x1f # 按数值解析十六进制,输出 31
printf '%5.2f\n' 3.14159 # 浮点保留两位并按宽度对齐
printf '%s\n' "${arr[@]}" # 数组逐行输出,替代手写循环转换符逐项读法
| 转换符 | 含义 | 常见用法 |
|---|---|---|
| %s | 字符串 | 最通用,配合宽度如 %-16s 做对齐 |
| %d | 十进制整数 | 识别 0x 十六进制与 0 八进制前缀 |
| %q | shell 转义形式 | 把任意字符串转成可直接粘贴执行的写法 |
| %05d | 补零定宽整数 | 生成 00001 这类编号 |
| %-10s | 左对齐固定宽度 | 表格输出,宽度为负数表示右侧补空格 |
| %% | 字面百分号 | 漏写会把后面的字符当作转换符解析 |
bash 内建的 printf 在参数多于格式符时会把格式串循环使用,参数不足时按 0 或空串补齐,不会报错。生成重复行时可以借这个特性,但也意味着拼错参数数量不会得到任何提示。
需要打印真正的百分号必须写两个百分号;写成单个百分号时后续字符会被当成转换符,输出错乱甚至报 invalid format,而脚本未必立刻失败。
printf 的浮点是双精度,参与前会先做字符串到数值的转换。对精度敏感或涉及金额、大整数的场景改用 awk、bc 处理,避免进制与舍入细节带来的偏差。