侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 744 篇文章
  • 累计创建 64 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

AWK(7)之内建函数

zze
zze
2019-12-25 / 0 评论 / 0 点赞 / 690 阅读 / 6485 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

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

gawk 编程语言提供了不少内置函数,可进行一些常见的数学、字符串以及时间函数运算。你可以在 gawk 程序中利用这些函数来减少脚本中的编码工作。

数学函数

如果你有过其他语言的编程经验,可能就会很熟悉在代码中使用内建函数来进行一些常见的数学运算。 gawk 编程语言不会让那些寻求高级数学功能的程序员失望。
下表列出了 gawk 中内建的数学函数:

函数描述
atan2(x, y)x/y 的反正切,xy 以弧度为单位
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() 函数会返回一个随机数,但这个随机数只在 01 之间(不包括 01)。要得到更大的数,就需要放大返回值。
产生较大整数随机数的常见方法是用 rand() 函数和 int() 函数创建一个算法。

x = int(10 * rand())

这会返回一个 0~9(包括 09)的随机整数值。只要为你的程序用上限值替换掉等式中的 10 就可以了。
除了标准数学函数外, gawk 还支持一些按位操作数据的函数。

  • and(v1, v2):执行值 v1v2 的按位与运算;
  • compl(val):执行 val 的补运算;
  • lshift(val, count):将值 val 左移 count 位;
  • or(v1, v2):执行值 v1v2 的按位或运算;
  • rshift(val, count):将值 val 右移 count 位;
  • xor(v1, v2):执行值 v1v2 的按位异或运算;

位操作函数在处理数据中的二进制值时非常有用。

字符串函数

gawk 编程语言还提供了一些可用来处理字符串值的函数,如下表:

函数描述
asort(s [,d]) 将数组 s 按数据元素值排序。索引值会被替换成表示新的排序顺序的连续数字。另外,如果指定了 d,则排序后的数组会存储在数组 d
asorti(s [,d]) 将数组 s 按索引值排序。生成的数组会将索引值作为数据元素值,用连续数字索引来表明排序顺序。另外如果指定了 d,排序后的数组会存储在数组 d
gensub(r, s, h [, t])查找变量 $0 或目标字符串 t(如果提供了的话)来匹配正则表达式 r。如果 h 是一个以 gG 开头的字符串,就用 s 替换掉匹配的文本。如果 h 是一个数字,它表示要替换掉第 hr 匹配的地方
 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])sFS 字符或正则表达式 r(如果指定了的话)分开放到数组 a 中。返回字段的总数
sprintf(format, variables)用提供的 formatvariables 返回一个类似于 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

但一些字符串函数的用法相当复杂。asortasorti 函数是新加入的 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() 函数的返回值也是这种形式。

0
AWK

评论区