目录
前言
awk的全称是(Aho Weinberger Kernaighan) 是以三位创始人的名字命名的,awk在linux 环境下处理文本和数据是非常高效和灵活的,是一个强大的分析过滤工具。
提示:以下是本篇文章正文内容,下面案例可供参考
一、语法
awk 选项 '条件{指令}' 文件名
说明:多个条件和指令用 逗号"," 隔开;{} 表示逐行;支持for循环,if语句,逻辑语句,等式判断。默认使用单引号‘ 如果是单引号里面的是字符串,那么字符串需要用双引号引起来
- 选项
-F # 指定分隔符,不指定默认以空格为分隔符或者tab键为分隔符;分隔符可以使用正则表达式。
# 文本内容:cat test.txt
192.168.4.7 - - [07/Sep/2022:17:58:10 +0800] "GET / HTTP/1.1" 200 12 "-" "curl/7.29.0"
# 截取上述文本test.txt 中:10 +0800 的内容
awk -F'[/:]' '{print $6}' test.txt
# 这里使用了(/ 或 :) 作为分隔符; $6: 代表只取满足条件的第6列
输出结果为:
10 +0800
-v # 代表可以调用shell 变量
[root@bigdata02 ~]# x=hello
[root@bigdata02 ~]# awk -v y=$x 'BEGIN{print y}'
hello
- 指令
print # 打印输出
$列号 # awk内置的变量,表示列号
awk 的内置变量有:
$1,2,3,... # 数字代表列号
$0 # 文本当前行的全部内容,等价于{print}
NF #当前行的列数, $NF最后列
NR #当前行的行号
# 提取文件中 /etc/passwd 的用户名信息
[root@bigdata02 ~]# awk -F: '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
...
# 以:号为分隔符,打印最后一列
[root@bigdata02 ~]# awk -F: '{print $NF}' /etc/passswd
# 打印倒数第二列
[root@bigdata02 ~]# awk -F: '{print $(NF-2)}' /etc/passwd
二、过滤时机
首先awk的是逐行对内容进行处理,容许在处理之前做一些准备工作和在结束之后做总结。
语法
awk 'BEGIN{指令} {指令} END{指令}' 文件名
说明
BEGIN{} # 在还没有处理内容之前,执行的指令,只执行1次
{} # 在处理过程中需要执行的内容,执行n次,以就是执行的主体
END{} # 在处理内容结束之后,需要执行的内容,只执行1次
# 统计文件/etc/passwd 文件有多少行
[root@bigdata02 ~]# awk 'BEGIN{i=0} {i=i+1} END{print i}' /etc/passwd
28
BEGIN{} ,{} ,END{} 是可以单独存在的,当{} 或 END{} 对真实的数据内容进行处理,当没有输入时,会处于等待状态。
三、常用指令和使用方法
1.条件判断
-
1.1 正则表达式
用法: ~/正则表达式/ # !~ 符号代表不匹配 双/为固定模式
例如:
#查找文件中以root开头的行
[root@bigdata02 ~]# awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 匹配第一列为root关键字的行信息
[root@bigdata02 ~]# awk -F: '$1~/root/ {print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
# 匹配第一列 不为 root 关键字的行信息
[root@bigdata02 ~]# awk -F: '$1!~/root/ {print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
...
-
1.2 数字/字符串比较
==,!= ,>= ,>,<=,<
# 提取文件中第一列为root用户的解释器信息
[root@bigdata02 ~]# awk -F: '$1=="root" {print $NF}' /etc/passwd
/bin/bash
2.逻辑运算
-
2.1 逻辑或 || 与 &&
# 打印文件中解释器不为 nologin 并且不是root 用户的信息
[root@bigdata02 ~]# awk -F: '$NF!~/nologin/ && $1!="root" {print}' /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
saas:x:1000:1000::/home/saas:/bin/bash
mysql:x:1001:1001::/home/mysql:/bin/bash
-
2.2 算术运算
求余 %
# 打印偶数行
[root@bigdata02 ~]# cat -n /etc/passwd | awk '$NR%2==0 {print}'
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
...
# 打印在200数字中,能被3和13整的数
[root@bigdata02 ~]# seq 200 | awk '$1%3==0 && $1%13==0 {print}'
39
78
117
156
195
3.流程控制
-
3.1 if 语句
用法:
awk 选项 '{if(条件){指令}}' # 单分支
或
awk 选项 '{if(条件1){指令}
else if(条件2)
{指令2} else{其他}}' # 多分支
注意:多分支时else if 之间有空格哟!!!
例如:
# 统计 /etc 目录下 不同文件类型的个数
[root@bigdata02 ~]# ll /etc/ | awk '{if($1~/^-/){ x++}else if($1~/^l/){y++}else{z++} } END{print "普通文件数:" x"\n超链接:"y"\n其他:"z}'
普通文件数:91
超链接:14
其他:85
-
3.2 for 循环
用法:
for(表达式1;表达式2;表达式2){指令} # 表达式1:初始值,表达式2:条件 ,表达式3:步长
或
for( list in 列表) #一般用户循环数组使用
例如:
# 打印 0-9 的数字
[root@bigdata02 ~]# awk 'BEGIN{for(i=0;i<10;i++){print i}}'
0
1
2
3
4
5
6
7
8
9
############### 数组 ###########
说明: 数组的是可以存放多个变量的,awk 数组组下标支持的有:数字,字符串(用双引号)并且在循环遍历时为数组的下标。
#定义变量age,下标为姓名的数组
awk 'BEGIN{age["james"]=25;age["xf"]=30;print age["james"],age["xf"]}'
#遍历数组
awk 'BEGIN{age[0]=25;age[1]=30;for (i in age) {print i,age[i]}}'
# ip[$NF]++ #每出现一个相同的值数值值是累计+1,常用统计下标值出现的次数,$NF代表每行最后一列的值
总结
awk 在进行复杂或又有一定逻辑关联的日志分析中是非常有用的,重要的是理解awk过滤的时机和基本场景的运用。