AWK


awk的概述

GUN gawk
[root@m01 ~]# which awk
/usr/bin/awk
[root@m01 ~]# ll /usr/bin/awk
lrwxrwxrwx. 1 root root 4 May 14 16:36 /usr/bin/awk -> gawk

awk的执行流程

# 执行流程
- 读取文件前---------------- BEGIN{}
- 读取文件时----------------    {}
- 读物文件后----------------   END{}

*awk读取文件内容之前*
1.读取文件之前,先看命令的选项,例如 -F,-v
2.如果写了BEGIN{}则先在BEGIN{}中的指令
*awk读取文件内容之时*
1.awk在读取文件时,也是一行一行的读
2.读取一行之后,判断是否满足条件,如果是,则执行{对应动作}
3.如果不满足条件,awk继续读取下一行,直到满足条件或者到文件的最后一行
*awk读取文件内容之后*
1.所有文件读取完成之后,走END{}中的指令

在 awk 中行和列,一般不叫行和列,专业称呼
行:记录 record
列:字段 field


awk -F: 'BEGIN{print "name","uid"}{print $1,$3}END{print "文件处理完成"}'/etc/passwd |column -t
name uid
root 0
column表格打印
选项 作用
-s 指定分隔符
-t 创建一个表格,使用列对齐
-c 指定输出高度
-x 按行而不是案列进行填充
######### 示例 1:基本用法 ##########
文本如下:
Name Age City
Alice 30 New York
Bob 25 Los Angeles
Charlie 35 Chicago


 ###########  -t  #######
[root@web01 ~]# column -t q.txt 
Name     Age  City
Alice    30   New      York
Bob      25   Los      Angeles
Charlie  35   Chicago

########### -s 指定分割符号 #######
[root@web01 ~]# column -s5 -t q.txt
Name Age City
Alice 30 New York
Bob 2               Los Angeles
Charlie 3           Chicago

############# -x 进行填充 #########
[root@web01 ~]# column -x  w.txt
1 2 3	4 5 6	7 8 9
[root@web01 ~]# column -x -t  w.txt
1  2  3
4  5  6
7  8  9
[root@web01 ~]# cat w.txt 
1 2 3
4 5 6
7 8 9

行 NR 的过滤

逻辑关系符号 作用
|| 或者
&&
!
# NR
number of record

[root@web01 ~]# cat 1.txt 
aaa 111
bbb 222
ccc 333co'l
ddd 666

##### 取出第一行 #####
[root@web01 ~]# awk NR==1 1.txt 
aaa 111
[root@web01 ~]# awk '2>NR' 1.txt   必须带着单引号
aaa 111

##### 取第一行到第三行 ######
[root@web01 ~]# awk NR==1,NR==3 1.txt 
aaa 111
bbb 222
ccc 333
[root@web01 ~]# awk 'NR>=1 && NR<=3' 1.txt 
aaa 111
bbb 222
ccc 333
[root@web01 ~]# awk 'NR<=3' 1.txt 
aaa 111
bbb 222
ccc 333
-----------------# 错误写法  注意 大于和小于都要再等于前面  awk 'NR>=1 && NR=<3' 1.txt 

# 打印包含关键字的行
[root@m01 ~]# awk '/xxx/' 123.txt
xxx:123

# 打印从第三行到最后一行
[root@m01 ~]# awk 'NR>=3' /etc/passwd

# 打印第三行和第一行
[root@web01 ~]# awk 'NR==1 || NR==3' /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 排除打印第3行 和第7行 
awk 'NR != 3 && NR != 7' filename

## awk控制结束标记
awk -vRS=: 'NR==2' 123.txt
xxx:123
yyy:456
zzz:789

-vRS=  设置换行符号

awk 选项表

选项 作用
-F 指定分隔符
-vOFS 指定输出后的分隔符
-vFS= 指定分割符号
-VRS= 指定换行符号
############ 示范 #############
123.txt
Zeng Laoshi     133411023        :110:100:75
Deng Ziqi	   44002231         :250:10:88
Zhang Xinyu    877623568          :120:300:200
Gu Linazha      11029987          :120:30:79
Di Lireba         253097001       :220:100:200
Jiang Shuying     535432779        :309:10:2
Ju Jingyi        68005178          :130:280:385
Zhang Yuqi       376788757         :500:290:33
Wen Zhang         259872003       :100:200:300

# 找出姓氏为zhang的人 他们的第二次捐款的数量和姓名
awk -F '[ :]+' 'BEGIN{print "姓名"" ""第二次捐款"}/^Zhang/{print $1,$2,$5}' 123.txt

# 显示所有25开头的qq号码和姓名
awk '$3 ~ /^25/{print $1,$2,$3}' 123.txt

# 显示qq最后一位是1/3的人的姓名和qq
awk '$3 ~ /(1|3)$/{print $1,$2,$3}' 123.txt

# 捐款数显示以$分隔
awk '{gsub(":","$");print $0}' 123.txt
sed s/:/$/g 123.txt

awk的模式

模式 作用 用法
BEGIN 读取文件之前就会执行(计算,打印) BEGIN{print 9/9}
END 日志分析后的一个结果,显示一些文件的尾部信息 END{print $0}
########## BEGIN ##########
[root@web01 ~]# awk 'BEGIN{print "1 + 1 = " 1+1}'
1 + 1 = 2

######### END ###########
[root@web01 ~]# awk 'BEGIN{print "1 + 1 = " 1+1}{print $6}END{print"运算结束"}'  1.txt 
1 + 1 = 2

运算结束

awk-表达式

### 正则表达式 ####
'//'     ------# 查询
$1 ~//   ------# 第一列查询 
$1 ~!//  ------# 第一列排除查询

#### 比较表达式 ####
NR==1
NR>=1
NR<=5
$>=100

###### 范围的表达 ########
---- # 1~20行
NR==1,NR==20
------ # 精确匹配字符串 从该字符串的行到啊另一个字符串的行
'/root/,/xxx/'
------- # 模糊匹配 从含有该字符串的行 到另一个 含有该字符串的行
'$1~/aa/,$1~/bb/'

awk的动作

print 打印
grub 替换
变量赋值
统计计算
# 统计/etc/service文件一共有多少行
{i++}
awk '{i++}END{print i}' /etc/services
11176

# 统计/etc/service空行的数量
^$
awk '/^$/{i++}END{print i}' /etc/services

###### 赋值  取值 #####
awk 'BEGIN{array[0]="aaa";array[1]="bbb"}'
awk 'BEGIN{array[0]="aaa";array[1]="bbb";print array[0],array[1]}'  ----> aaa bbb

##### 数组 ######
awk 'BEGIN{array[0]="aaa";array[1]="bbb";\
for (name in array){  \
print array[name]\
}}'
aaa
bbb

##### 判断 ######
# awk单分支判断
if ($1~/root/){
	print $1 $2
}
# 双分支
if(){
	print ...
	}else{
	print ...
}
# 多分支
if(){
	print ...
	}else if(){
			print ...
			}else{
			print
}


####### 循环 ########
数组专用循环
for(n in array){
	print n,array[n]
}
fot(i=1li<=10;i++){
	print i
}