awk 高级命令
前面写了几篇文章,关于sed 基础命令、sed 高级命令 及 awk 基础命令 的介绍及操作可以查看:
sed 和 awk 系列文章:
sed 基础命令:http://www.huangdc.com/109
sed 高级命令:http://www.huangdc.com/123
awk 基础命令 : http://www.huangdc.com/143
awk 高级命令:http://www.huangdc.com/146 (本文)
好吧,我们来看看awk 的高级命令 ,还是那句话高级的awk命令需要更大的决心来掌握,一旦你理解了这些命令,那么就可以认为自己是真正的awk主人了
在 awk 基础命令 我简单总结了: 程序设计模型 , 模式匹配 , 系统变量 , 记录和字段 , 表达式 , 关系操作符和布尔操作符 ,格式打印,向脚本传递参数
接下来我们看看 awk 高级命令 : awk中的条件和循环结构的语法借鉴于C程序设计语言。
awk 条件语句
条件语句用于在执行操作之前做一个测试。模式匹配规则本质就是影响往输 入循环的条件表达式;条件语句以if开头,并计算放在圆括号中的表达式。 语法是:(条件表达式可能包含算术运算符、关系操作符、布尔操作符)
if(expression){
action1;
action3
} [else action2]
实例:将成绩分级表示出 A、B、C、D等级 ;A(大于等于90分),B(大于等于80 且 小于 90),C (大于等于60 且小于80),D (其他)
[DcHuang@vm200-78 ~]$ cat test.txt
路人甲 60
路人乙 77
路人丁 88
路人AA 90
路人BB 64
路人CC 76
路人DD 69
[DcHuang@vm200-78 ~]$ [DcHuang@vm200-78 ~]$ awk '{if($2>=60 && $2<80){print $0" C"}else if($2>=80 && $2<90){print $0" B"}else if($2>=90){print $0" A"}else{print $0" D"}}' test.txt
路人甲 60 C
路人乙 77 C
路人丁 88 B
路人AA 90 A
路人BB 64 C
路人CC 76 C
路人DD 69 C
awk循环
循环是一种用于重复执行一个或者多个操作的结构。在awk中循环结构可以用while、 do或for语句来指定
while循环语法:
while(condition)
action
do循环语法:(do语句是while循环的一个变型)
do
action
while(condition)
for循环语法:(for语句是和while循环一样,但是语法更紧凑)
for(set_counter ; test_counter ; increment_counter)
action
#set_counter 计数器变量初始值; test_counter 测试的条件; increment_counter 递增计数器
for循环实例:
。。。。
awk 数组
数组是可以用来存储一组数据的变量。通常这些数据之间具有某种暧昧关系。 数组中的每一个元素通过他们在数组中的小标来访问。每个下标都用方括号 括起来,给数组中的一个元素赋值如下:
array[subscript]=value
在awk中不必指明数组的大小,只需要为数组指定标识符。向数组元素赋值是最容易的事。
关联数组(重点):在awk中,所有的数组都是关联数组。关联数组的独特之处 在于它的下标可以是一个字符或者一个数值,关联数组在数组的下标和元素之间建 立了一种“关联”,每个元素都有两个相关的值:元素的下标和元素的值。
它的强大功能就是可以使用字符串作为一个数据的下标
array[“string”]=”BASIC”
有一组特殊的循环语法可以访问关联数值的所有元素。for循环的一个版本:
for( variable in array)
do something whith array[variable]
#variable in array: 依次获取关联数值的下标
关联数组实例:查看且统计并发请求数及其TCP连接状态
[root@local103-35 ~]# netstat -an | awk '/^tcp/ {++S[$NF]} END{for(a in S) print a, S[a]}'
TIME_WAIT 7
ESTABLISHED 154
LISTEN 52
[root@local103-35 ~]#
1、测试数组中的成员资格
关键词in也是一个操作符,用在条件表达式中用来测试一个下标是否是数组的成员:
item in array
如果array[item]存在则返回1,否则返回0
if( “item” in array ) print “Found item”
2、用split()创建数组
内置函数split()能够将任何字符串分解到数组的元素中。语法:
n=split(string, array, separator)
string是要被分割到名字为array的元素中的输入字符串。数组的下标从1开始到n,n 即为数组中的元素的个数,元素根据指定的separator分割符来分解
3、删除数组元素,语法:
delete array[subscript]
awk函数
函数是一个独立的计算过程,它接受一些参数作为输入并返回一些值,awk 有许多内置函数。可以分为两组
1、算术函数
2、字符串函数
awk也支持用户 自定义函数,允许你编写自己的函数来扩展内置函数
awk内置算术函数 | 描述 |
---|---|
cos(x) | 返回x的余弦 |
exp(x) | 返回e的x次幂 |
int(x) | 返回x的整数部分的值 |
log(x) | 返回x的自然对数 |
sin(x) | 返回x的正弦 |
sqrt(x) | 返回x的平方根 |
atan2(y,x) | 返回y/x的的反正弦 |
rand() | 返回为随机数r,其中0<=r<1 |
[root@local103-35 ~]# echo '10' |awk '{print $1/3}'
3.33333
[root@local103-35 ~]#
## int 整数
[root@local103-35 ~]# echo '10' |awk '{print int($1/3)}'
3
awk字符串函数 | 描述 |
---|---|
gsub(r,s,t) | 在字符串t中用字符串s替换和正则表达式r匹配的所有字符串。返回替换的个数。如果没有指定t,默认$0 |
index(s,t) | 返回子串t在字符串s中的位置,如果没有指定s,则返回0 |
length(s,t) | 返回字符串s的长度,当没有给出s时,返回$0的长度 |
split(s,a,sep) | 创建数组 |
sub(r,s,t) | 在字符串t中用s替换正则表达式r的首次匹配 |
通常情况下,我们将函数定义放置脚本顶部的模式操作规则之前。函数用下面的语法定义:
function name(parameter-list){
statement
}
[root@local103-35 ~]# echo "2 22" |awk 'function FUNC(int1,int2) {return int1 + int2}{print FUNC($1,$2)}'
24
awk简单实例
1、对每行求和
awk ‘{s=0;for (i=0;i<NF;i++) s=s+$i; print s}’
2、对所有行所有字段求和
awk ‘{for (i=0;i<NF;i++) s=s+$i; END {print s+0}’
3、删除行首和行末的空格
awk ‘{ gsub(/^[ \t]+ | [ \t]+$/,””); print }’ |
4、删除每行的第二个字段
awk ‘{ $2 = “”; print }’
5、删除连续的重复行
awk ‘a != $0; { a = $0 }’
6、删除非连续的重复行
awk ‘!a[$0]++’
7、删除所有的空行
awk NF