正则之Awk
1.什么是awk:
awk不仅仅是一个文本处理工具,同时也是一门编程语言,
是linux上功能最强大的数据处理工具之一。
2.awk 语法格式:
awk [options] 'commands' filenames
awk [options] -f awk-script-file filenames
处理的文件是/etc/hosts 总共三行
BEGIN 行处理前动作 {}行处理中 END行处理后
BEGIN{print 1/2} {print "OK"} END{print "Over"}
0.5 ok GameOver
ok
ok
#命令 command
行处理前 行处理 行处理后
BEGIN{} {} END{}
#BEGIN发生在读文件之前
[root@Shell ~]# awk 'BEGIN{print 1/2}'
0.5
#BEGIN在行处理前,修改字段分隔符
[root@shell ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd
#BEGIN在行处理前,修改字段读入和输出分隔符
[root@shell ~]# awk 'BEGIN{FS=":" OFS="---"}{print $1,$2}' /etc/passwd
#示例:
[root@shell ~]# awk 'BEGIN{print 1/2} {print "ok"} END{prrint "Game Over"}' /etc/hosts
0.5
ok
ok
ok
Game Over
=========================================
3.awk 命令格式:
#示例1,匹配awk 'pattern' filename
[root@shell ~]# awk '/root/' /etc/passwd
#示例2,处理动作 awk '{action}' filename
[root@shell ~]# awk -F:'{print $1}' /etc/passwd
=========================================
示例3,匹配+处理动作 awk 'pattern {action}' filename
[root@shell ~]# awk -F ':' '/root/{print $1,$3}' /etc/passwd
[root@shell ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd
示例4:判断大于多少则输出什么内容 command |awk 'pattern {action}'
[root@shell ~]# df |awk '/\/$/ {if($3>50000)print $4}'
4.Awk工作原理:
# awk -F:'{print $1,$3}' /etc/passwd
1.awk将文件中的每一行作为输入,并将每一行赋值给内部变量$0,以换行符结束。
2.awk开始进行字段分隔,每个字段存储在已编号的变量中,从$1开始[默认空格分隔]
3.awk默认字段分隔符是由内部FS变量来确定,可以使用-F修订。
4.awk行处理时使用了print函数打印分割后的字段。
5.awk在打印后的字段加上空格,因为$1,$3之间有一个逗号,逗号被映射至OFS内部变量中,
称为输出字段分隔符。OFS默认为空。
6.awk输出之后,将从文件中获取另一行,并将其存储在$0中,覆盖原来的内容,
然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕。
=========================================
例子1:
[root@shell ~]# cat awk_file.txt
ll 1989 55 56 63
kk 1990 60 57 64
hh 1991 70 58 65
jj 1992 80 59 66
mm 1993 90 60 67
1)awk指定多个分隔符,awk默认以空白行作为分隔符
#1.如何查看文件中的第一列:
[root@shell ~]# awk '{print $1}' awk_file.txt
ll
kk
hh
jj
mm
#2.如果有的文件不是以空格为分隔符怎么办?
比如:/etc/passwd
[root@shell ~]# awk -F ":" '{print $2}' awk_file.txt
1989 55 56 63
1990 60 57 64
[root@shell ~]# awk -F "[: ]" '{print $2}' awk_file.txt
1989
1991
1992
1993
1994
=========================================
#[: ]+
1.连续的多个冒号当一个分隔符
2.连续的多个空格当一个分隔符
3.连续空格和冒号也当做一个分隔符
"#[: \t]+"
4.连续空格和tab也当做一个分隔符
5.连续tab也当做一个分隔符
6.连续的冒号空格tab都算一个分隔符
===================================
例子2:
统计一行里有多少个数量,一共5个
[root@shell ~]# awk '{print NF}' awk_file.txt
5
5
5
5
5
======================================
1.awk内置变量NF,保存每行的最后一列
#1.通过print打印,NF和$NF,你发现了什么?
[root@shell ~]# awk '{print NF,$NF}' awk_file.txt
5 63
5 64
5 65
5 66
5 67
#2.使用$NF为什么就能成功?(因为NF变量保存的是每一行的最后一列)
[root@shell ~]# awk '{print $NF}' awk_file.txt
63
64
65
66
67
#3.如果一个文件很长,靠数列数需要很长的时间,
那么如何快速打印倒数第二列?
[root@shell ~]# awk '{print $(NF-1)}' awk_file.txt
56
57
58
59
60
2)awk内置变量NR,表示记录行号
#1.使用pring打印NR,会发现NR会记录每行文件的行号
[root@shell ~]# awk '{print NR,$0}' awk_file.txt
1 ll 1989 55 63
2 kk 1990 60 64
--------------------------------------------
#2.[root@shell ~]# awk 'NR==3{print $0}' awk_file.txt
hh 1991 70 58 65
#3.那如果我们想打印第二行到第三行的内容怎么办?
[root@shell ~]# awk 'NR>1&&NR<4 {print NR,$0}' awk_file.txt
2 kk 1990 60 57 64
3 hh 1992 70 58 65
#4.那如果只想打印第三行,该怎么办?
[root@shell ~]# awk 'NR==3 {print NR,$00}' awk_file.txt
3 hh 1992 70 53 63
#5.那如果既想打印第三行,又想打印第一列?
[root@shell ~]# awk 'NR==3 {print NR,$1}' awk_file.txt
3 hh
===============================================
4.awk内置变量,$0保存当前记录的内容
[root@shell ~]# awk '{print $0}' /etc/passwd
5.awk内置变量,FS指定字段分隔符,默认是空格?
#以冒号作为字段分隔符:
[root@shell ~]# awk -F:'/root/{print $1,$3}' /etc/passwd
[root@shell ~]# awk '{BEGIN{FS=":"} {print $1,$3} ' /etc/passwd
内置变量
NF #记录每行内容的最后一列,通常记录的是一个整数
NR #记录行号
FS #指定字段分隔符
OFS #指定输出字段分隔符
$0 #代表每行的所有内容
$1,$2 #指定字段分隔符后,每列的内容
print #输出内容
printf #格式化输出
===============================================
5.awk模式匹配与动作处理
awk语句都由模式和动作组成,模式部分动作语句何时触发事件,如果省略模式部分,动作将时刻保持执行状态,模式可以是条件语句或复合语句或正则表达式。
(1)正则表达式
#匹配记录(整行)
[root@shell ~]# awk '/^root/' /etc/passwd
#匹配字段,匹配操作符(~ !~)
[root@shell ~]# awk '$1~/^root/' /etc/passwd
(2)条件表达式
[root@shell ~]# awk -F: '{if($3>300) print $0}' /etc/passwd
(3)条件判断:
//统计系统用户数量
[root@shell ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd
[root@shell ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd
网友评论