禅道博客

分享专业技术知识,文章内容干货满满

读书笔记《Linux命令行与shell脚本编程大全》第22章

2023-12-21 15:16:33
胡爱荣
原创 791
摘要:本文是作者《Linux命令行与shell脚本编程大全》第22章的读书和学习笔记。


1. 使用变量

gawk编程语言支持两种不同类型的变量:内建变量和自定义变量。


1.1 内建变量

Gawk程序使用内建变量来引用程序数据里的一些特殊功能。

(1)字段和记录分隔符变量


采用字段宽度进行分隔的例子:
只要设置了FIELDWIDTH变量,gawk就会忽略FS变量,并根据提供的字段宽度来计算字段。

(2)数据变量

FNR变量含有当前数据文件中已处理过的记录数,NR变量则含有已处理过的记录总数。

FNR变量的值在gawk处理第二个数据文件时被重置了,而NR变量则在处理第二个数据文件时会继续计数。

1.2 自定义变量

Gawk自定义变量名支持任意数量的字母、数字、下划线,但不能以数字开头,且变量名区分大小写。

(1)在脚本中给变量赋值

(2)在命令行上给脚本赋值

2. 处理数组

2.1 定义数组变量

数组变量赋值的格式:var[index] = element;
  • Var:变量名;
  • index:关联数组的索引值;
  • element:数据元素值。

2.2 遍历数组变量

2.3 删除数组变量

delete array[index]

3. 使用模式

正则表达式

匹配操作符
匹配操作符是波浪线:~

数学表达式

可以使用任何常见的数学比较表达式:等于==、小于等于<=、小于<、大于等于>=、大于>,表达式必须是完全匹配,数据必须和模式严格匹配。

4. 结构化命令

If语句,支持两种格式:
  • if (condition)
  • statement1
  • if (condition) statement1


while语句

while (condition)
{
Statements

}

do-while语句
do
{
statements

} while (condition)

for语句
for( variable assignment; condition; iteration process)

5. 格式化打印

  • 格式化打印命令:printf
  • printf命令的格式:printf "format string", var1, var2…
format string用文本元素和格式化指定符来具体指定如何呈现格式化输出。格式化指定符会指明显示项什么类型的变量及如何显示。gawk会将每个格式化指定符作为占位符,第一个格式化指定符对应列出第一个变量,第二个对应第二个比那两。

格式化指定符采用如下格式:
%[modifier]control-letter,control-letter是一个单字符代码,指明显示什么类型的数据,modifier定义了可选的格式化特性。

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


6. 内建函数

数学函数

  • int():不会取四舍五入进位后的值。
  • rand():只创建0和1之间的随机数,不包含0或1。


除标准数学函数外,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的按位异或运算。

字符串函数
  • 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中的所有字符转换成大写。

时间函数


时间函数常用来处理日志文件,而日志文件则常含有需要进行比较的日期。通过将日期的文 本表示形式转换成epoch时间(自1970-01-01 00:00:00 UTC到现在的秒数),可以轻松地比较日期。

下面的例子中用systime函数从系统获取当前的epoch时间戳,然后用strftime函数将它转换成用户可读的格式

7. 自定义函数

定义函数
function name([variables])
{
Statements

}

函数名必须能够唯一标识函数。

使用自定义函数

在定义函数时,它必须出现在所有代码块之前(包括BEGIN代码块)。下面的例子中,定义了myprint()函数,它会格式化记录中的第一个和第四个数据字段以供打印输出。

创建函数库
gawk支持将多个函数放到一个文件中,需要使用-f命令行参数来使用它们。但不能将-f命令行参数和内联gawk脚本放到一起使用,不过可以在同一个命令行中使用多个-f参数。

8. 实例

数据文件scores中包含了两支队伍(每队2名选手)的保龄球比赛得分情况,每位选手都有3场比赛的成绩,每位选手由位于第二列的队名来标识。下面的例子对每队的成绩进行了排序,并计算了总分和平均分。

for循环中的第一条语句过滤出数据文件中的队名,然后使用uniq命令返回不重复的队名。 for循环再对每个队进行迭代。

利用gawk的-v选项来确定队名是否和正在进行循环的队名相符,如果队名相符,代码会对数据记录中的三场比赛得分求和,然后将每条记录的值再相加,只要数据记录属于同一队。
暂时没有记录
评论通过审核后显示。