3. Awk
3.1 语法
AWK 命令模式:地址+动作
awk '/search pattern/ {actions}' file
地址通过正则表达式匹配得到,AWK默认采用ERE 模式。
3.2 参数
| 参数 | 含义 |
|---|---|
| -F | field-separator, 字段分隔符 |
| -f | 引入awk脚本 |
| -v | -v var=val, 设置变量值 |
字段 与 记录
记录: 类似于数据库中的一行数据,一行数据称为记录。默认通过换行符进行分隔。
字段: 一条记录由多个字段组成。默认采用空格进去分隔。
记录:Gawk is the GNU Project’s implementation of the AWK programming language.
字段:默认通过空格分隔字段,因而上述记录中,每个单词为一个字段。
3.3 变量
| 变量名 | 含义 |
|---|---|
| RS | 输入记录分隔符,默认换行 |
| FS | 输入字段分隔符,默认空格 |
| ORS | 输出记录分隔符,默认换行 |
| OFS | 输出字段分隔符,默认空格 |
| NF | 当前记录中字段数量 |
| NR | 当前已经处理的记录数 |
cat text
a:b:c
awk:sed:grep
awk -F: '{print $1}' text
awk -v FS=: '{print $1}' text
awk -F: '{print $NF}' text
可以通过改变内置变量来控制各个分隔符。字段分隔符既可以通过改变内置变量,又可以通过参数-F进行指定。
3.4 脚本
3.3.1 表达式
操作符
| 操作符 | 含义 |
|---|---|
| +, -, *, /, % | 加,减,乘,除, 取余 |
| ++, - - | 自增,自减 (both前置and后置) |
| &&,双竖线 | 逻辑操作 |
| ?: | 三元条件, exp1 ? exp2 : exp3 |
| …… | …… |
in: 判断数组是否存在某个索引。awk中数组都是关联数组。
code> echo 1 | awk '{ my_arr[1] = 3; if (1 in my_arr) print "exist"; }'
out> exist
delete: 删除数组中索引+元素。
code> echo 1 | awk '{my_arr[1] = 3; delete my_arr[1]; if (!(1 in my_arr)) print "not exist";}'
out > not exist
exit: 退出awk语句,停止执行。
BEGIN {
print “begin";
}
{
print "body"
}
END {
print "end"
}
情况一:如果exit出现在BEGIN块中,则Body语句块与END语句块都会被执行。
情况二:如果exit出现在body块中,则BEGIN,END语句块会被执行
情况三:如果exit出现在END块中,则BEGIN,body语句块被执行。
BEGIN {
print "begin"
}
{
print "body1"
exit 1
print "body2"
};
END {
print "end"
};
code> echo 1 | awk -f test.awk
out > begin
body1
end
break: 循环控制
continue 循环控制
3.3.2 语句
if (condition) statement [ else statement ]
while (condition) statement
do statement while (condition)
for (expr1; expr2; expr3) statment
for (var in array) statement
3.3.3 函数
自定义函数
function function_name(parameter list) { statements }
NOTE: 函数参数为局部变量,而函数内部定义的变量为全局变量
cat test.awk
function myawk(text)
{
my_text = text" world!"
}
{
myawk("hello")
print my_text
}
---------------
echo 1 | awk -f test.awk
hello world!
内置函数
数学函数
sqrt
sin
rand
srand
echo 1 | awk '{srand(); print rand();}'
字符串函数
length
tolower
toupper
index(s, t):返回s中匹配t的位置。
code> echo 1 | awk '{s="spch2008"; print index(s, "2008");}'
out > 5
match(s, r): 在s中匹配r,返回匹配s的位置。内置变量RSTART返回匹配位置,RLENGTH返回匹配长度。
code> echo 1 | awk '{s="spch2008"; match(s, "2008"); print RLENGTH;}'
out > 4
NOTE: index 与 match的区别:
t表示普通串,而r表示可以使用正则。
split(s, a, [, r]): 将字符串s,以r分隔,分隔后,放于数组a中;返回数组大小。
code> echo 1 | awk '{s="a:b:c:d"; split(s, a, ":"); for(slot in a) printf "%s ", a[slot]}'
out > d a b c
Note: for (item in array) 语句不保证按顺序输出,若要按顺序输出,采用for(i = 1; i < n; i++)
sprintf(fmt, expr-list):类似C的sprintf,格式化字符串。通过返回值,得到格式的字符串。
code> echo 1 | awk '{print sprintf("Hello %s", "Tom")}'
out > Hello Tom
strtonum(str): 字符串转数字。若字符串有前导0,则认为是8进制;若前导0x,则认为16进制。
code> echo 1 | awk '{print strtonum("0x10")}'
out > 16
sub(r, s, [, t]): 将t中,匹配r的部分,替换成s。若t为空,则使用$0。
code> echo 1 | awk '{t="spch2008"; sub("/2008/", "1234", t); print t}'
out > spch1234
substr(s, i [,n]): 字符串截取。从位置i开始,截取n个;若n为空,则截取到字符串尾。
code> echo 1 | awk '{print substr("spch2008", 5, 4)}'
out > spch2008
IO函数
print: 简单打印
printf: 类似于C的printf
echo 1 | awk '{msg = "Hello"; printf "%s World!\n", msg;}'
next: 停止对当前记录进行任何规则得处理,强制处理下一条记录。
本文详细介绍了AWK的基本概念、语法、参数、变量、脚本编写技巧及内置函数等内容,涵盖记录与字段的处理、变量的使用、表达式与语句的运用,以及如何通过改变内置变量来控制分隔符。此外,还展示了如何通过脚本实现复杂的数据处理任务,包括数组操作、循环控制、函数定义等。通过实例解析,读者能够全面掌握AWK的强大功能并应用于实际数据处理场景。
1882

被折叠的 条评论
为什么被折叠?



