AWK语言第二版 2.Awk实战 2.1个人计算

2.Awk实战

注:第二版的第2章是全新的。

第一版的第2章,是对Awk语言的详细说明。作者考虑到里面又长又干,不符合现代读者的习惯,于是在第二版中,将原第2章全部挪到 附录A(参考手册) 里面。

第一版的附录A是Awk语言总结,是参考手册的简化版,在第二版废弃。

第一版的附录B是练习答案,也在第二版去掉,改成放到网上。

Awk非常适用于制作小工具或者个人使用的脚本,它们可以帮你完成重复性的工作,或者处理一些(别人不关心但只有你在乎的)特别古怪的计算。

本章我们会看到这样一些样例,这些特定的程序不一定刚好适合你(运气好的话能碰到几个),但它们也许能启发你写出一些自己的程序,或者能给出一些编程技巧供你使用。

本章围绕着如下内容来组织:简单计算,基本的选择、转换和汇总操作,这些都是Awk最初的设计意图。每个例子除了本身是有趣或有用的,还能展示一些Awk语言本身的特性,并说明一些有用的编程技巧。一些例子不仅仅涉及Awk,还包含一些其他的标准Unix工具,以及对Unix环境的高效利用。

2.1个人计算

Awk是个不错的可编程计算器,你可以用它的计算封装成命令,并加入到你的个人工具箱。本节给出了我们觉得有用的几个小程序。

体重指数BMI

体重指数BMI是一个广泛使用的身体脂肪度量指标,公式为 bmi = weight / height 2。

“正常”的BMI范围在18到25之间,25到30为“超重”,30以上为“肥胖”。官方的定义使用了米和千克做单位,但下面的例子用的是英寸和磅,所以必须转换下:1千克=2.2磅,1英寸=2.54厘米。

# bmi计算

awk 'BEGIN { print "enter pounds inches" }
     { printf("%.1f\n", ($1/2.2) / ($2 * 2.54/100) ^ 2) } '

把上面的内容存到一个可执行文件中并命名为 bmi,就能把它当作程序来运行了。作者运行的效果是:

$ bmi
enter pounds inches
190 74
24.4

所以作者“差不多”正常。

运行敏感性测试(?)也很方便,比如评估节食效果或测量错误:

$ bmi
enter pounds inches
195 74
25.1
200 75
25.1

单位转换

上面BMI样例中的转换系数正确吗?如果不记得了,可以使用Unix程序 units ,它给出了几百种单位转换系数:

$ units
586 units, 56 prefixes
You have: inches
You want: meters
        * 0.0254
        / 39.370079
You have: pounds
You want: kg
        * 0.45359237
        / 2.2046226

下面我们自己写一个类似功能的 cf 程序来做常用的度量单位转换,但用起来更方便:我们不问用户想做什么操作,只要用户在命令行参数提供一个数值,cf 就把所有单位的双向转换系数都打印出来。cf 程序最初是作为一个 华氏-摄氏(Celsius to Fahrenheit)温度转换工具,这也是 cf 名字的由来。例如,外面的温度是 7℃,对应多少华氏度?

$ cf 7
7 C = 44.6 F;  7 F = -13.9 C

随着时间推移,加入了更多的转换,比如长度和重量。74英寸是多少厘米?74千克是多少磅?

$ cf 74
74 C = 165.2 F;  74 F = 23.3 C
74 cm = 29.1 in;  74 in = 188.0 cm
74 kg = 162.8 lb;  74 lb = 33.6 kg

cf 程序会把所有都打出来,用户自己选择想看的。

下面是 cf 程序的源代码。里面使用了内置数组 ARGV 来获取所需的命令行参数。所有代码都写在BEGIN 块里面,不会去读任何文件。

# cf: 温度、长度、重量 单位转换

awk 'BEGIN {
  t = ARGV[1]  # 首个命令行参数
  printf("%s C = %.1f F;  %s F = %.1f C\n",
    t, t*9/5 + 32, t, (t-32)*5/9)
  printf("%s cm = %.1f in;  %s in = %.1f cm\n",
    t, t/2.54, t, t*2.54)
  printf("%s kg = %.1f lb;  %s lb = %.1f kg\n",
    t, 2.2*t, t, t/2.2)
}' $*

脚本里面的 $* 是 shell的表示法,用来表示程序接收到的所有参数,shell会将其展开为字符串列表传给程序。大部分情况下传给awk的参数是文件名,不过在 cf 这里,第一个参数是要转换的数字,其他参数被忽略。

Awk将程序被调用时的参数储存在数组 ARGV 中,ARGV[1]是第一个参数,ARGV[2]是第二个,以此类推直到 ARGV[ARGC - 1]ARGC 是所有参数的数量,ARGV[0]是程序名,通常是awk。在后面的例子里会有更多ARGV的信息,也可以参考附录 A.5.5。

关于Shell脚本的提醒

上面的 bmi 和 cf 程序叫做“shell脚本”:用脚本语言写程序,并保存在可执行文件中,这样它们就能和用编译型语言(如C语言)编写并编译后得到的可执行程序一样的方式,被操作系统执行了。要让一个文件在Unix系统中可执行,需要使用 chmod (change mode)命令

$ chmod +x bmi cf

如果该脚本放在你的shell搜索路径中(通常是 $HOME/bin),你就能像使用内置命令一样使用它们,前面的例子就是如此。

你可能感兴趣的:(AWK,linux,开发语言)