AWK(6)之格式化打印

AWK(6)之格式化打印

微信搜索 zze_coding 或扫描 👉 二维码关注我的微信公众号获取更多资源推送:

本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。

你可能已经注意到了 print 语句在 gawk 如何显示数据上并未提供多少控制。你能做的只是控制输出字段分隔符(OFS)。如果要创建详尽的报表,通常需要为数据选择特定的格式和位置。
解决办法是使用格式化打印命令,叫作 printf。如果你熟悉 C 语言编程的话, gawk 中的 printf 命令用法也是一样,允许指定具体如何显示数据的指令。
下面是 printf 命令的格式:

printf "format string", var1, var2 . . .

format string 是格式化输出的关键。它会用文本元素和格式化指定符来具体指定如何呈现格式化输出。格式化指定符是一种特殊的代码,会指明显示什么类型的变量以及如何显示。gawk 程序会将每个格式化指定符作为占位符,供命令中的变量使用。第一个格式化指定符对应列出的第一个变量,第二个对应第二个变量,依此类推。
格式化指定符采用如下格式:

%[modifier]control-letter

其中 control-letter 是一个单字符代码,用于指明显示什么类型的数据,而 modifier 则定义了可选的格式化特性。下表列出了可用在格式化指定符中的控制字母。

控制字母描述
c将一个数作为 ASCII 字符显示
d显示一个整数值
id
e用科学计数法显示一个数
f显示一个浮点值
g用科学计数法或浮点数显示(选择较短的格式)
o显示一个八进制
s显示一个文本字符串
x显示一个十六进制值
X显示一个十六进制值,但用大写字母 A~F

因此,如果你需要显示一个字符串变量,可以用格式化指定符 %s。如果你需要显示一个整数值,可以用 %d%i%d 是十进制数的 C 风格显示方式)。如果你要用科学计数法显示很大的值,就用 %e 格式化指定符。

$ gawk 'BEGIN{
> x = 10 * 1000;
> printf "The result is: %e \n", x;
> }'
The result is: 1.000000e+04

除了控制字母外,还有 3 种修饰符可以用来进一步控制输出:

  • width:指定了输出字段最小宽度的数字值。如果输出短于这个值,printf 会将文本右对齐,并用空格进行填充。如果输出比指定的宽度还要长,则按照实际的长度输出;
  • prec:这是一个数字值,指定了浮点数中小数点后面位数,或者文本字符串中显示的最大字符数;
  • -:指明在向格式化空间中放入数据时采用左对齐而不是右对齐;

可以用 printf 命令来帮助格式化输出,使得输出信息看起来更美观。

$ cat test4.txt 
Riley Mullen
123 Main Street
Chicago, IL 60601
(312)555-1234

Frank Williams
456 Oak Street
Indianapolis, IN 46201
(317)555-9876

Haley Snell
4231 Elm Street
Detroit, MI 48201
(313)555-4938
$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%s %s\n", $1, $4}' test4.txt 
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Haley Snell (313)555-4938

它会产生跟 print 命令相同的输出。printf 命令用 %s 格式化指定符来作为这两个字符串值的占位符。
注意,你需要在 printf 命令的末尾手动添加换行符来生成新行。没添加的话,printf 命令会继续在同一行打印后续输出。
下一步,用修饰符来格式化第一个字符串值。

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%16s %s\n", $1, $4}' test4.txt 

image.png

通过添加一个值为 16 的修饰符,我们强制第一个字符串的输出宽度为 16 个字符。默认情况下,printf 命令使用右对齐来将数据放到格式化空间中。要改成左对齐,只需给修饰符加一个减号即可。

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1, $4}' test4.txt

image.png

现在看起来专业多了!
printf 命令在处理浮点值时也非常方便。通过为变量指定一个格式,你可以让输出看起来更统一。

$ cat test6.txt 
130 120 135
160 113 140
145 170 215
$ gawk '{
> total = 0;
> for (i = 1; i < 4; i++){
>     total += $i;
> }
> avg = total / 3;
> printf "Average: %5.1f\n", avg;
> }' test6.txt
Average: 128.3
Average: 137.7
Average: 176.7

可以使用 %5.1f 格式指定符来强制 printf 命令将浮点值近似到小数点后一位。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.zze.xyz/archives/awk6.html

Buy me a cup of coffee ☕.