本部分内容参考自《Linux命令行与shell脚本编程大全 第3版》。
gawk 编程语言提供了不少内置函数,可进行一些常见的数学、字符串以及时间函数运算。你可以在 gawk 程序中利用这些函数来减少脚本中的编码工作。
数学函数
如果你有过其他语言的编程经验,可能就会很熟悉在代码中使用内建函数来进行一些常见的数学运算。 gawk 编程语言不会让那些寻求高级数学功能的程序员失望。
下表列出了 gawk 中内建的数学函数:
| 函数 | 描述 | 
|---|---|
| atan2(x, y) | x/y的反正切,x和y以弧度为单位 | 
| cos(x) | x的余弦,x以弧度为单位 | 
| exp(x) | x的指数函数 | 
| int(x) | x的整数部分,取靠近零一侧的值 | 
| log(x) | x的自然对数 | 
| rand() | 比 0 大比 1 小的随机浮点值 | 
| sin(x) | x的正弦,x以弧度为单位 | 
| sqrt(x) | x的平方根 | 
| srand(x) | 为计算随机数指定一个种子值 | 
虽然数学函数的数量并不多,但 gawk 提供了标准数学运算中要用到的一些基本元素。 int() 函数会生成一个值的整数部分,但它并不会四舍五入取近似值。它的做法更像其他编程语言中的 floor 函数。它会生成该值和 0 之间最接近该值的整数。
这意味着 int() 函数在值为 5.6 时返回 5,在值为 -5.6 时则返回 -5。
rand() 函数非常适合创建随机数,但你需要用点技巧才能得到有意义的值。rand() 函数会返回一个随机数,但这个随机数只在 0 和 1 之间(不包括 0 或 1)。要得到更大的数,就需要放大返回值。
产生较大整数随机数的常见方法是用 rand() 函数和 int() 函数创建一个算法。
x = int(10 * rand())
这会返回一个 0~9(包括 0 和 9)的随机整数值。只要为你的程序用上限值替换掉等式中的 10 就可以了。
除了标准数学函数外, gawk 还支持一些按位操作数据的函数。
- and(v1, v2):执行值- v1和- v2的按位与运算;
- compl(val):执行- val的补运算;
- lshift(val, count):将值- val左移- count位;
- or(v1, v2):执行值- v1和- v2的按位或运算;
- rshift(val, count):将值- val右移- count位;
- xor(v1, v2):执行值- v1和- v2的按位异或运算;
位操作函数在处理数据中的二进制值时非常有用。
字符串函数
gawk 编程语言还提供了一些可用来处理字符串值的函数,如下表:
| 函数 | 描述 | 
|---|---|
| asort(s [,d]) | 将数组 s按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。另外,如果指定了d,则排序后的数组会存储在数组d中 | 
| asorti(s [,d]) | 将数组 s按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表明排序顺序。另外如果指定了d,排序后的数组会存储在数组d中 | 
| gensub(r, s, h [, t]) | 查找变量 $0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果h是一个以g或G开头的字符串,就用s替换掉匹配的文本。如果h是一个数字,它表示要替换掉第h处r匹配的地方 | 
|  gsub(r, s [,t]) | 查找变量 $0或目标字符串t(如果提供了的话)来匹配正则表达式r。如果找到了,就全部替换成字符串s | 
| index(s, t) | 返回字符串 t在字符串s中的索引值,如果没找到的话返回0 | 
| length([s]) | 返回字符串s的长度;如果没有指定的话,返回 $0的长度 | 
| match(s, r [,a]) | 返回字符串 s中正则表达式r出现位置的索引。如果指定了数组a,它会存储s中匹配正则表达式的那部分 | 
| split(s, a [,r]) | 将 s用FS字符或正则表达式r(如果指定了的话)分开放到数组a中。返回字段的总数 | 
| sprintf(format, variables) | 用提供的 format和variables返回一个类似于printf输出的字符串 | 
| sub(r, s [,t]) | 在变量 $0或目标字符串t中查找正则表达式r的匹配。如果找到了,就用字符串s替换掉第一处匹配 | 
| substr(s, i [,n]) | 返回 s中从索引值i开始的n个字符组成的子字符串。如果未提供n,则返回s剩下的部分 | 
| tolower(s) | 将 s中的所有字符转换成小写 | 
|  toupper(s) | 将 s中的所有字符转换成大写 | 
一些字符串函数的作用相对来说显而易见。
$ gawk 'BEGIN{x = "testing"; print toupper(x); print length(x) }'
TESTING
7
但一些字符串函数的用法相当复杂。asort 和 asorti 函数是新加入的 gawk 函数,允许你基于数据元素值(asort)或索引值(asorti)对数组变量进行排序。这里有个使用 asort 的例子。
$ gawk 'BEGIN{                                                   
arr1["a"]=22;
arr1["b"]=4;
arr1["c"]=8;
asort(arr1,arr2);
for(i in arr2){
    print "index: ",i," value: ",arr2[i];
}                                        
}'
index:  1  value:  4
index:  2  value:  8
index:  3  value:  22
新数组 arr 含有排序后的原数组的数据元素,但索引值现在变为表明正确顺序的数字值了。
split 函数是将数据字段放到数组中以供进一步处理的好办法。
$ gawk -F, '{
> split($0,arr);
> print arr[1],arr[5];
> }' test3.txt
data11 data15
data21 data25
data31 data35
 新数组使用连续数字作为数组索引,从含有第一个数据字段的索引值 1 开始。
时间函数
gawk 编程语言包含一些函数来帮助处理时间值,如下表所示:
| 函数 | 描述 | 
|---|---|
| mktime(datespec) | 将一个按 YYYY MM DD HH MM SS [DST]格式指定的日期转换成时间戳值 | 
|  strftime(format [,timestamp]) | 将当前时间的时间戳或 timestamp(如果提供了的话)转化格式化日期(采用 shell 函数date()的格式) | 
| systime() | 返回当前时间的时间戳 | 
时间函数常用来处理日志文件,而日志文件则常含有需要进行比较的日期。通过将日期的文本表示形式转换成 epoch 时间(自 1970-01-01 00:00:00 UTC 到现在的秒数),可以轻松地比较日期。
下面是在 gawk 程序中使用时间函数的例子。
$ gawk 'BEGIN{
timeNum = systime()
currTime = strftime("%Y-%m-%d %H:%M:%S",timeNum)
print currTime
}'
2019-12-25 14:44:11
该例用 systime 函数从系统获取当前的 epoch 时间戳,然后用 strftime 函数将它转换成用户可读的格式,转换过程中使用了 shell 命令 date 的日期格式化字符。
这里时间戳是指自
1970-01-01 00:00:00 UTC到现在,以秒为单位的计数,通常称为 epoch time。systime()函数的返回值也是这种形式。
-de8bd8f33c3e44a59907dafe1884f228.png) 
       
       
         
       
          
评论区