- 第六章 awk应用
- awk的基础应用
作用:awk是数据处理工具,sed是对整行处理,而awk是对一行中分成数字段来处理
awk从1行到最后一行,如匹配成功,则执行用户操作,如匹配失败,则不做任何处理
格式:awk [-F field-separator] 'commands' filename
[-F域分隔符]是可选的
commands 是awk要执行的命令动作
filename是要处理的文件
选项 | 含义 |
-F fs | 指定以 fs 作为输入行的分隔符,awk 命令默认分隔符为空格或制表符。 |
-v var=val | 在执行处理过程之前,设置一个变量 var,并给其设备初始值为 val。 |
awk 的强大之处在于commands,它由2部分组成,分别为匹配规则和执行命令
'匹配规则{执行命令}'
awk命令的完整格式:awd [-F field-separator] '匹配规则{执行命令}' filename
执行命令部分需要用大括号({})括起来
任何awk语句都是由'匹配规则{执行命令}'组成,一个awk中可以有多个语句。匹配规则决定执行命令的执行条件
匹配规则(即执行条件)
条件类型 | 条 件 | 说 明 |
awk保留字 | BEGIN | 在awk程序一开始,尚未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次 |
awk保留字 | END | 在awk程序处理完所有数据,即将结束时执行。END 后的动作只在程序结束时执行一次 |
关系运算符 | > | 大于 |
< | 小于 | |
>= | 大于等于 | |
<= | 小于等于 | |
== | 等于。用于判断两个值是否相等。如果是给变量赋值,则使用"=” | |
!= | 不等于 | |
匹配表达式 | ~(匹配) | value ~ /regexp/ 如果value匹配/regexp/,则返回真 |
!~(不匹配) | value !~ /regexp/ 如果value不匹配/regexp/,则返回真 | |
正则表达式 | /正则表达式/ | 如果在“//”中可以写入字符,则也可以支持正则表达式,如:/root/表示匹配含有root的行。 |
逻辑运算符 | && | 逻辑与 |
|| | 逻辑或 |
例如:
判断$7(第7个数据字段)的值是否匹配正则表达式/bash$/
判断$7(第7个数据字段)的值是否不匹配正则表达式/bash$/
awk 使用数据字段变量
$0 代表整个文本行;
$1 代表文本行中的第 1 个数据字段;
$2 代表文本行中的第 2 个数据字段;
$n 代表文本行中的第 n 个数据字段。
执行命令(动作action)
awk的执行命令在大括号{ }内指明。动作大多数用来打印(即print指令)
动作(Action):
格式化输出(print);
流程控制语句(if、while、for等);
例如:显示passwd文件中第1个第6个字段的信息
“\t” #指的是Tab分隔符,空格
“\n” #指的是另起一行
awk中的BEGIN和END
语法:
awk [options] 'BEGIN{ print "start" } 匹配规则{ commands } END{ print "end" }' filename
BEGIN模块:在 awk 程序处理完所有数据,即将结束时执行的
END模块:END 后的动作只在程序结束时执行一次
awk工作过程
awk变量
awk自定义变量
awk内置变量(预定义变量)
$n 当前记录(当前行)的第n个字段,比如n为1表示第一个字段,n为2表示第二个字段
$0 这个变量包含执行过程中当前行的文本内容
FILENAME 当前输入文件的名
FS 字段分隔符(默认是任何空格)
NF 表示字段数,在执行过程中对应于当前的字段数
NR 表示记录数,在执行过程中对应于当前的行号
FNR 各文件分别计数的行号
awk范例
范例1:提取网卡的IP地址
范例2:关系运算符的使用
范例3:打印passwd文件中用户UID小于10的用户名和它登录使用的shell
[root@localhost ~] # awk -F: '$3<10{print $1"<=====>"$NF}' /etc/passwd
范例4-:打印系统中能够正常登录的普通用户
[root@localhost ~]# awk -F: '$3>=1000 && $NF=="/bin/bash"{print $1,$NF}' /etc/passwd
范例5:统计当前内存的使用率
说明:printf命令与print命令类似,用于显示输出的,只不过printf命令可以按照指定的格式显示输出。
printf命令格式:printf “打印格式” 显示内容
其中:%2.f就是打印格式,表保留小数后两位,f代表浮点数
2.awk控制语句
2.1、if语句
if (条件) print
if(条件){print}else{print}
if(条件){print}else if(条件){print}else{print}
范例1:
[root@localhost ~]# awk -F: '{if($3<1000) {print "system_user="$1} else {print "program_user="$1}}' /etc/passwd
范例2:统计分区使用率,输出超过15%的分区信息
[root@localhost ~]# df -hT | awk -F"[ %]+" '/^\/dev/ {if($6>15)print $1,$6"%"}'
说明: -F"[ %]+"表示将空格或%当做分隔符。
if语句使用的地方===》对awk来说,要对取得的整行或某个字段做条件判断
2.2、while循环
语句:while(条件){语句} 如果条件为“真”进入循环,条件为“假”退出循环
范例:
[root@localhost ~]# cat b.txt
20 10 4
4 45 10
19 19 19
[root@localhost ~]# awk '{total=0;i=1;while(i<=NF){total+=$i;i++}; print total}' b.txt
34
59
57
说明:while语句使用的地方===》在awk中对一行内容中的多个字段一个个处理。
2.3、for循环
语法:for(变量赋值;条件;迭代){命令}
[root@localhost ~]# awk '{total=0;for(i=1;i<=NF;i++){total+=$i}; print total}' b.txt
34
59
57
特殊作用:它能够用来遍历数组中的元素
语法:for (var in array){语句}
2.4、偶数(next)
打印奇数或偶数行
[root@localhost ~]# awk 'NR%2==0{print NR,$0}' /root/score.txt
2.5、数组
1.定义
数组是一个包含一系列元素的集合。
格式如下:
abc[1]=”xiaohong”
abc[2]=”xiaolan”
解释:
abc :为数组名称
[1]、[2]:为数组元素下标,可以理解为数组的第1个元素、数组的第2个元素
”xiaohong”、”xiaolan”: 元素内容
2.数组变量赋值的格式
2.1、var[index]=element:
说明:
- var====>是数组名
- element===>是数组的元素值
- index===>是关联数组的下标
2.2、数字做数组下标:
array[1]=”sun”
array[2]=”kai”
2.3、符串做数组下标:
array[“first”]=”www”
array[“last”]=”name”
我们在引用数组变量的时候,必须要包含它的下标值,然后通过下标值来提取它相对应的元素值
[root@localhost ~]# awk 'BEGIN{
> test["a"]="Mon"
> test["b"]="Tue"
> test["c"]="Wor"
> print test["b"]
> }'
显示结果:
Tue
也可以写成:
# awk 'BEGIN{test["a"]="Mon";test["b"]="Tue";test["c"]="Wed";print test["b"]}'
3.遍历数组中的元素
若要遍历数组中的每个元素,可以使用for循环:
for(var in array){print array[var]}
说明: for循环在每次循环时会将数组array的一个下标值赋给变量var,然后去执行大括号中的语句。还有一个需要注意的地方就是这个变量var中存储的是下标值而不是数组的元素值。我们可以把这个变量当作是数组的下标,然后来提取出对应元素值
[root@localhost ~]# awk 'BEGIN{
> test["a"]="Mon"
> test["b"]="Tue"
> for(i in test)
> {print "Index:"i,"-----value:"test[i]}
> }'
Index:a -----value:Mon
Index:b -----value:Tue
4.数组应用范例
array[“index”]++ 每循环一次这个索引所对应的元素值加1(初始值默认是0)
它经常用来统计某个东西出现的次数,可以这样表示:
范例1:统计Listen和Estableshed出现的次数
范例2:统计相同的网站出现的次数
测试文件:
[root@localhost ~]# cat c.txt
http://www.163.com
http://www.163.com
http://www.163.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.baidu.com
http://www.cnblogs.com
http://www.qq.com
http://www.163.com
http://www.baidu.com
http://www.baidu.com
http://www.qq.com
http://www.163.com
http://www.baidu.com
[root@localhost mnt]# awk -F"[/]+" '{print $2}' c.txt | sort
www.163.com
www.163.com
www.163.com
www.baidu.com
www.baidu.com
www.baidu.com
www.baidu.com
www.cnblogs.com
www.qq.com
[root@localhost mnt]# awk -F"[/]+" '{print $2}' c.txt |sort|uniq -c
5 www.163.com
7 www.baidu.com
1 www.cnblogs.com
2 www.qq.com
注:
sort命令用于将文本文件内容加以排序
uniq命令用于检查及删除文本文件中重复出现的行列,一般与sort命令结合使用。
也可以通过下面的操作统计每个网站出现的次数:
[root@localhost ~]# awk -F"[/]+" '{times[$2]++}END{for(i in times){print i,times[i]}}' c.txt
www.qq.com 2
www.cnblogs.com 1
www.baidu.com 7
www.163.com 5
3.cut命令
定义
cut是一个选取命令,就是将一段数据经过分析,取出我们想要的。一般来说,选取信息通常是针对“行”来进行分析的,并不是整篇信息分析的。
主要参数
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
范例:
[root@localhost ~]# awk -F: '{print $NF}' /etc/passwd
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
[root@localhost ~]# cut -d: -f7 /etc/passwd
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
4.脚本综合
需求
类似++++系统管理工具箱++++++
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
写法:
[root@localhost ~]# cat system.sh
#!/bin/bash
menu(){
cat<<eof
++++系统管理工具箱++++++
h 显示命令帮助
f 显示磁盘使用情况
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
eof
}
#显示文件系统的磁盘使用情况统计
Fdisk(){
df -Th
}
#显示硬盘容量、已使用容量、空闲容量
Diskinfo(){
df -Th|awk '/^\/dev/{print $1"\t\t"$3"\t\t\t"$4"\t\t\t"$5}'
}
#查看内存占用前10进程
Memtop10(){
ps aux --sort -pmem | head -11 | awk '{print $1"\t"$2"\t"$4"\t"$11}'
}
#查看CPU占用前10进程
Cputop10(){
ps aux --sort -pcpu|head -11|awk '{print $1"\t"$2"\t"$3"\t"$11}'
}
#显示帮助信息
menu
while true
do
read -p "input a choose(h for help):" OP
case $OP in
h)
clear
menu;;
f)
echo "显示文件系统的磁盘使用情况统计"
Fdisk;;
d)
echo "显示硬盘容量、已使用容量、空闲容量"
Diskinfo;;
m)
echo "内存占用前10进程"
Memtop10;;
u)
echo "CPU占用前10进程"
Cputop10;;
q)
exit;;
*)
echo "输入错误"
esac
done