我正在 bash 中尝试 printf 格式,并且遇到了这段代码:
#/bin/bash
divider===============================
divider=$divider$divider
header="\n %-15s %8s %10s %11s\n"
format=" %-15s %08d %10s %11.2f\n"
width=55
printf "$header" "ITEM NAME" "ITEM ID" "COLOR" "PRICE"
printf "%$width.${width}s\n" "$divider"
printf "$format" \
Triangle 13 red 20 \
Oval 204449 "dark blue" 65.656 \
Square 3145 orange .7
我感兴趣的那一行是这样写的:
printf "%$width.${width}s\n" "$divider"
该变量引用在做什么?这是什么意思?
答案1
该代码"%$width.${width}s\n"
生成适合以下用户使用的格式字符串printf
在您发布的脚本中,width
已分配了值55
,因此$width
和都${width}
被 bash 扩展为55
:整个第一个参数 toprintf
扩展为%55.55s\n
;这是格式%s
,带有字段宽度和精度说明符,要求打印恰好 55 个字符。给定此时变量的值divider
,这将简单地打印一行 55 个等号。打印相同内容的一种可能更简单的方法是perl -e 'print "=" x 55, "\n"'
。
字段宽度说明符的最简单形式是整数:这要求printf
至少使用这么多字符进行打印。如果相应的参数需要的字符数少于此打印数量,则输出将在左侧填充空格。
精度说明符的最简单形式是一个点后跟一个整数:当应用于 时%s
,这设置要打印的最大字符数。 (对于数字类型它有不同的含义。)
作为对评论的回应,我还将提到一些有关 shell 变量扩展的内容(完整的解释可以通过在 bash 文档中搜索“参数扩展”找到,另请参阅$VAR 与 ${VAR} 以及引用或不引用):
当一个变量(例如
x
)被设置后,则$x
扩展为 的值x
。如果该值包含空格,则扩展将是几个单词。这就是为什么在上面的代码中它很重要,例如,"$format"
在双引号内:这会强制扩展为单个单词(否则,printf
会看到第一个参数%-15s
,后跟一个参数%8s
等,而不是接收整个将字符串格式化为单个参数)。允许写入
${x}
而不只是$x
扩展变量x
;在上面的例子中,"${width}s"
,有必要这样做,因为如果写了"$widths"
,那么 bash 会尝试获取变量 的值widths
,而该值是未设置的,从而导致空扩展。