目录
一. awk命令简介
1. awk版本
2. awk与vim的区别
3. awk与sed的区别
4. awk工作原理
5. awk格式
6. awk常用选项
二. awk基础用法
1. awk基础用法
2. BEGIN和END语句块
3. 指定分隔符
4. 首尾关键字
三. awk内置变量
1. FS变量
2. OFS变量
3. RS变量
4. NF变量
5. NR变量
①. 打印出限定行
②. 打印出偶数或奇数行
③. 打印出范围行
6. 自定义变量
四. awk匹配模式
1. 模式为空
2. 正则匹配
3. NR范围行匹配
4. 关系表达式
五. 条件判断
六. for循环
七. 关联数组
八. awk脚本
九. awk案例
1. 提取分区利用率
2. 提取用户名和uid号
3. 提取/bin/bash结尾的用户并统计个数
4. 提取IP地址
5. 提取出所有普通用户
6. 提取10:00 到 11:00 之间的日志
7. 提取状态次数
8. 统计/etc/fstab文件中每个文件系统类型出现的次数
9. 统计/etc/fstab文件中每个单词出现的次数
一. awk命令简介
1. awk版本
AWK:原先来源于 AT & T 实验室的的AWK
NAWK:New awk,AT & T 实验室的AWK的升级版
GAWK:即GNU AWK。所有的GNU/Linux发布版都自带GAWK,它与AWK和NAWK完全兼容
在centos7中默认使用的是gawk。
2. awk与vim的区别
awk:文本处理工具,加载一行,处理一行
vim:文本处理工具,将整个文件加载到内存中处理,内存不足文件大小时,打不开文件
3. awk与sed的区别
awk:处理文件内容时,一般以行为处理单位
sed:处理文件内容时,一般以列为处理单位
4. awk工作原理
①. 执行BEGIN{action;… }语句块中的语句
②. 从文件或标准输入(stdin)读取一行,然后执行pattern{ action;… }语句块,它逐行扫描文件,
从第一行到最后一行重复这个过程,直到文件全部被读取完毕。
③. 当读至输入流末尾时,执行END{action;…}语句块
BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
pattern语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块
5. awk格式
awk [选项] '模式 {处理动作}'
特别注意:awk命令需要使用单引号
6. awk常用选项
选项 | 说明 |
- F | 指定分隔符 |
- v | 指定自定义变量 |
- f | 脚本 |
二. awk基础用法
1. awk基础用法
注意点:
①. 可以不加导向符,默认读取后面的文件内容
②. 打印的字符串需要加双引号,否则不识别
2. BEGIN和END语句块
①. BEGIN代码块:
在读取文件之前执行,且执行一次
在BEGIN代码块中,无法使用$0或其他一些特殊变量
②. END代码块:
在读取文件完成之后执行,且执行一次
有END代码块,必须有要读取的数据(可以是标准输入)
END代码块中可以使用$0等一些特殊变量,只不过这些特殊变量保存的是最后一轮awk循环的数据
③. main代码块
读取文件时循环执行,默认情况下每读取一行,就执行一次main代码块
main代码块可以有多个
3. 指定分隔符
4. 首尾关键字
^加关键字是以这个关键字为开头过滤
关键字加&是以这个关键字为结尾过滤
三. awk内置变量
内置变量 | 说明 |
FS | 指定每行文本的字段分隔符,缺省为空格或制表符(tab)。与 “-F”作用相同 -v "FS=:" |
OFS | 输出时的分隔符 |
NF | 当前处理的行的字段个数 |
NR | 当前处理的行的行号(序数) |
$0 | 当前处理的行的整行内容 |
$n | 当前处理行的第n个字段(第n列) |
FILENAME | 被处理的文件名 |
RS | 行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n |
1. FS变量
指定每行文本的字段分隔符,缺省(默认)为空格或制表符(tab)。
"-F" 作用与 -v "FS=:" 相同
注意:-F 与 -FS 一起使用时,-F 的优先级高
2. OFS变量
3. RS变量
在一个文件中,默认的换行符是$,RS的作用是把默认换行符换成指定换行符
4. NF变量
NF的作用是打印每一行有多少个字段
5. NR变量
NR的作用是显示行号
①. 打印出限定行
②. 打印出偶数或奇数行
③. 打印出范围行
6. 自定义变量
四. awk匹配模式
awk '模式{处理动作}'
PATTERN:根据pattern条件,过滤匹配的行,再做处理
1. 模式为空
如果模式为空,表示每一行都匹配成功,相当于没有额外条件
awk -F: '{print $1,$3}' /etc/passwd
2. 正则匹配
/regular expression/:仅处理能够模式匹配到的行,需要用/ /括起来,固定搭配
模糊匹配,用~表示包含,!~表示不包含
#匹配从以root开头的行到以adm开头的行
awk -F: '/^root/,/^adm/{print NR,$1"\t"$3}' /etc/passwd
3. NR范围行匹配
#比较操作符
==, !=, >, >=, <, <=
#逻辑
与:&&,并且关系
或:||,或者关系
非:!,取反
4. 关系表达式
关系表达式结果为“真”才会被处理
真:结果为非0值,非空字符串
假:结果为空字符串或0值
五. 条件判断
六. for循环
for(expr1;expr2;expr3) {statement;…}
for(variable assignment;condition;iteration process) {for-body}
for(var in array) {for-body}
awk 'BEGIN{sum=0;for(i=1;i<=100;i++){sum+=i};print sum}'
5050
for((i=1,sum=0;i<=100;i++));do let sum+=i;done;echo $sum
5050
七. 关联数组
awk的数组为关联数组
awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";print weekdays["mon"]}'
awk '!line[$0]++' dupfile
awk '{print !line[$0]++, $0, line[$0]}' dupfile
awk '{!line[$0]++;print $0, line[$0]}' dupfile
遍历数组:
for(var in array) {for-body}
awk 'BEGIN{students[1]="lizong";students[2]="liuzong";students[3]="kunzong";for(x in students){print x":"students[x]}}'
ss -nta|awk 'NR!=1{print $1}'|sort
ss -nta|awk 'NR!=1{state[$1]++}'
ss -nta|awk 'NR!=1{state[$1]++}END{for(i in state){print i,state[i]}}'
八. awk脚本
将awk程序写成脚本,直接调用或执行
[root@centos7 ~]#vim passwd.awk
{if($3>=1000)print $1,$3}
[root@localhost data]#awk -F: -f passwd.awk /etc/passwd
nfsnobody 65534
zhangsan 1000
mysql 1001
[root@centos7 ~]#cat test.awk
#!/bin/awk -f
#this is a awk script
{if($3>=1000)print $1,$3}
[root@centos8 ~]#chmod +x test.awk
[root@centos8 ~]#./test.awk -F: /etc/passwd
nobody 65534
wang 1000
mage 1001
九. awk案例
1. 提取分区利用率
#提取分区利用率
df | awk '{print $5}'
#去除%,以多位空格和%为分隔符提取
df | awk -F"( +|%)" '{print $5}'
df | awk -F"[[:space:]]+|%" '{print $5}'
df | awk -F"[ %]+" '{print $5}'
df | awk -F"[ %]+" '{print $(NF-1)}'
2. 提取用户名和uid号
#提取用户名和uid号
awk -F: '{print $1,$3}' /etc/passwd
awk -v "FS=:" '{print $1,$3}' /etc/passwd
3. 提取/bin/bash结尾的用户并统计个数
#过滤以/bin/bash结尾的行并统计个数
awk 'BEGIN {x=0};/\/bin\/bash$/;{x++};END{print x}' /etc/passwd
#过滤以非/bin/bash结尾的行并统计个数
awk 'BEGIN {x=0};/\/bin\/bash$/ {x++;print x,$0};END{print x}' /etc/passwd
4. 提取IP地址
#提取当前主机IP地址
hostname -I | awk '{print $1}'
ifconfig ens33 | sed -n '2p' |awk '{print $2}'
ifconfig ens33 | grep mask | awk '{print $2}'
ifconfig ens33 | awk 'NR==2{print $2}'
5. 提取出所有普通用户
#提取出普通用户
awk -F: '$3>=1000{print NR,$0}' /etc/passwd
#过滤出uid号大于等于1000的用户
6. 提取10:00 到 11:00 之间的日志
#提取10:00到12:00之间的日志
awk '/10:00/,/12:00/{print $0}' 日志文件
7. 提取状态次数
ss -nta|awk 'NR!=1{print $1}'|sort
ss -nta|awk 'NR!=1{state[$1]++}'
ss -nta|awk 'NR!=1{state[$1]++}END{for(i in state){print i,state[i]}}'
8. 统计/etc/fstab文件中每个文件系统类型出现的次数
cat /etc/fstab | grep -v '^#' | grep -v '^$' | awk '{print $3}' | sort | uniq -c
9. 统计/etc/fstab文件中每个单词出现的次数
grep -Eo "\b[a-zA-Z]+\b" /etc/fstab | wc -l