【Linux正则表达式之awk】

🍖awk

Linux三剑客awk:

awk是一个强大的Linux命令,有强大的文本格式化能力,好比将一些文本数据格式化成专业的Excel表的样式

awk早期在Unix上实现,我们使用的awk是gawk,是GNU awk的意思

[root@kvm01 ~]# which awk && ll /usr/bin/awk 
/usr/bin/awk
lrwxrwxrwx. 1 root root 4 1128 10:52 /usr/bin/awk -> gawk

awk更是一门编程语言,支持条件判断、数组、循环等功能

  • 再谈三剑客
# 再谈三剑客:
- grep,擅长单纯的查找或匹配文本内容
- awk,更适合编辑、处理匹配到的文本内容
- sed,更适合格式化文本内容,对文本进行复杂的处理
awk基础:

awk语法

awk [option] 'pattern[action]' file

awk 参数 '条件动作' 文件

在这里插入图片描述

  • action指的是动作,awk擅长文本格式化,且输出格式化后的结果,因此最常用的动作就是printprintf

  • 准备一份测试文件

cat > awk.txt <<-EOF
pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
EOF
  • 输出第一列和第二列的字符:
# 输出第一列
[root@kvm01 ~]# awk '{print $1}' awk.txt 
pyyu1
pyyu6
pyyu11
pyyu16
pyyu21
pyyu26
pyyu31
pyyu36
pyyu41
pyyu46

# 输出第二列
[root@kvm01 ~]# awk '{print $2}' awk.txt  
pyyu2
pyyu7
pyyu12
pyyu17
pyyu22
pyyu27
pyyu32
pyyu37
pyyu42
pyyu47

# 同时输出第一列和第二列
[root@kvm01 ~]# awk '{print $1 $2}' awk.txt 
pyyu1pyyu2
pyyu6pyyu7
pyyu11pyyu12
pyyu16pyyu17
pyyu21pyyu22
pyyu26pyyu27
pyyu31pyyu32
pyyu36pyyu37
pyyu41pyyu42
pyyu46pyyu47
  • 输出所有的字符:
[root@kvm01 ~]# awk '{print $0}' awk.txt 
pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
pyyu46 pyyu47 pyyu48 pyyu49 pyyu50

我们执行的命令式awk '{print $2}',没有使用参数和模式,$2表示输出文本的第二列信息

awk默认以空格为分隔符,且多个空格也识别为一个空格,作为分割符

awk是按行处理文件,一行处理完毕,处理下一行,根据用户指定分隔符去工作,没有指定则默认空格

指定了分隔符后,awk把每一行切割后的数据对应到内置变量

  • $0 表示整行
  • $NF 表示当前分割后的最后一列
  • 倒数第二列可以写成$(NF-1)
# 输出分割后的最后一列
[root@kvm01 ~]# awk '{print$NF}' awk.txt    
pyyu5
pyyu10
pyyu15
pyyu20
pyyu25
pyyu30
pyyu35
pyyu40
pyyu45
pyyu50

# 输出倒数第二列
[root@kvm01 ~]# awk '{print$(NF-1)}' awk.txt 
pyyu4
pyyu9
pyyu14
pyyu19
pyyu24
pyyu29
pyyu34
pyyu39
pyyu44
pyyu49
awk内置变量:
内置变量解释
$n指定分隔符后,当前记录的第n个字段
$0完整的输入记录
FS字段分隔符,默认就是空格
NF(Number of fields)分割后,当前行一共有多少个字段
NR(Number of records)当前记录数,行数
更多内置变量可以用man手册查看man awk
# 使用awk输出1,4,5列并添加分隔符
[root@kvm01 ~]# awk '{print $1,$4,$5}' awk.txt       
pyyu1 pyyu4 pyyu5
pyyu6 pyyu9 pyyu10
pyyu11 pyyu14 pyyu15
pyyu16 pyyu19 pyyu20
pyyu21 pyyu24 pyyu25
pyyu26 pyyu29 pyyu30
pyyu31 pyyu34 pyyu35
pyyu36 pyyu39 pyyu40
pyyu41 pyyu44 pyyu45
pyyu46 pyyu49 pyyu50

自定义输出内容:

awk,必须外层单引号,内层双引号

内置变量$1、$2都不得添加外双引号,否则会识别为文本,尽量别加引号

[root@kvm01 ~]# awk '{print "第一列",$1"第二列",$2"第三列",$3}' awk.txt 
第一列 pyyu1第二列 pyyu2第三列 pyyu3
第一列 pyyu6第二列 pyyu7第三列 pyyu8
第一列 pyyu11第二列 pyyu12第三列 pyyu13
第一列 pyyu16第二列 pyyu17第三列 pyyu18
第一列 pyyu21第二列 pyyu22第三列 pyyu23
第一列 pyyu26第二列 pyyu27第三列 pyyu28
第一列 pyyu31第二列 pyyu32第三列 pyyu33
第一列 pyyu36第二列 pyyu37第三列 pyyu38
第一列 pyyu41第二列 pyyu42第三列 pyyu43
第一列 pyyu46第二列 pyyu47第三列 pyyu48

[root@kvm01 ~]# awk '{print "第一列:"$1,"第二列:"$3}' awk.txt 
第一列:pyyu1 第二列:pyyu3
第一列:pyyu6 第二列:pyyu8
第一列:pyyu11 第二列:pyyu13
第一列:pyyu16 第二列:pyyu18
第一列:pyyu21 第二列:pyyu23
第一列:pyyu26 第二列:pyyu28
第一列:pyyu31 第二列:pyyu33
第一列:pyyu36 第二列:pyyu38
第一列:pyyu41 第二列:pyyu43
第一列:pyyu46 第二列:pyyu48

[root@kvm01 ~]# awk '{print "n1:"$1,"n2:"$3}' awk.txt             
n1:pyyu1 n2:pyyu3
n1:pyyu6 n2:pyyu8
n1:pyyu11 n2:pyyu13
n1:pyyu16 n2:pyyu18
n1:pyyu21 n2:pyyu23
n1:pyyu26 n2:pyyu28
n1:pyyu31 n2:pyyu33
n1:pyyu36 n2:pyyu38
n1:pyyu41 n2:pyyu43
n1:pyyu46 n2:pyyu48

[root@kvm01 ~]# awk '{print "每一行的内容是:"$0}' awk.txt 
每一行的内容是:pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
每一行的内容是:pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
每一行的内容是:pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
每一行的内容是:pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
每一行的内容是:pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
每一行的内容是:pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
每一行的内容是:pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
每一行的内容是:pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
每一行的内容是:pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
每一行的内容是:pyyu46 pyyu47 pyyu48 pyyu49 pyyu50

awk参数

参数解释
-F指定分隔字段符
-v定义或修改一个awk内部的变量
-f从脚本文件中读取awk命令
  • 准备测试文件:
[root@kvm01 ~]# cat shadow.txt 
root:$6$5H/KWlWFlGGuM4Ct$h9NrRwbTntw0vJ.Mqas2Be8TKyso.eKLGGkICpKjBbM0.yAx.V///MbKNnWiM1e/7q5EZxHqjW63mhPCe0YbR0::0:99999:7:::
bin:*:18353:0:99999:7:::
daemon:*:18353:0:99999:7:::
adm:*:18353:0:99999:7:::
lp:*:18353:0:99999:7:::
sync:*:18353:0:99999:7:::
shutdown:*:18353:0:99999:7:::
halt:*:18353:0:99999:7:::
mail:*:18353:0:99999:7:::
operator:*:18353:0:99999:7:::
games:*:18353:0:99999:7:::
ftp:*:18353:0:99999:7:::
nobody:*:18353:0:99999:7:::
systemd-network:!!:19324::::::
dbus:!!:19324::::::
polkitd:!!:19324::::::
sshd:!!:19324::::::
postfix:!!:19324::::::
chrony:!!:19324::::::
hsqldb:!!:19325::::::
mysql:!!:19328::::::

显示文件第五行:

# NR在awk中表示行号,NR==5表示行号是5的那一行
# 注意一个等于号,是修改变量值的意思,两个等于号是关系运算符,是"等于"的意思
[root@kvm01 ~]# awk 'NR==5' shadow.txt 
lp:*:18353:0:99999:7:::

[root@kvm01 ~]# cat -n shadow.txt | awk NR==5'{print$0}'
     5  lp:*:18353:0:99999:7:::
     
# 显示第五行的内容
[root@kvm01 ~]# awk NR==5'{print $0}' awk.txt 
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25

# 显示第五行和第六行
[root@kvm01 ~]# awk NR==5,NR==6'{print $0}' awk.txt 
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
pyyu26 pyyu27 pyyu28 pyyu29 pyyu30

显示文件2~5行:

[root@kvm01 ~]# awk 'NR==2,NR==5' awk.txt 
pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25

[root@kvm01 ~]# cat -n awk.txt | awk NR==2,NR==5
     2  pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
     3  pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
     4  pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
     5  pyyu21 pyyu22 pyyu23 pyyu24 pyyu25

给每一行的内容添加行号:

添加变量,NR等于行号,$0表示一整行的内容

{print}是awk的动作

[root@kvm01 ~]# awk '{print NR,$0}' awk.txt  
1 pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
2 pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
3 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
4 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
5 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
6 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
7 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
8 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
9 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
10 pyyu46 pyyu47 pyyu48 pyyu49 pyyu50

[root@kvm01 ~]# awk 'NR==10,NR==21{print NR,$0}' shadow.txt     
10 operator:*:18353:0:99999:7:::
11 games:*:18353:0:99999:7:::
12 ftp:*:18353:0:99999:7:::
13 nobody:*:18353:0:99999:7:::
14 systemd-network:!!:19324::::::
15 dbus:!!:19324::::::
16 polkitd:!!:19324::::::
17 sshd:!!:19324::::::
18 postfix:!!:19324::::::
19 chrony:!!:19324::::::
20 hsqldb:!!:19325::::::
21 mysql:!!:19328::::::

显示shadow文件的第一列,倒数第二和最后一列:

[root@kvm01 ~]# awk '{print $1,$(NF-1),$(NF-2)}' awk.txt  
pyyu1 pyyu4 pyyu3
pyyu6 pyyu9 pyyu8
pyyu11 pyyu14 pyyu13
pyyu16 pyyu19 pyyu18
pyyu21 pyyu24 pyyu23
pyyu26 pyyu29 pyyu28
pyyu31 pyyu34 pyyu33
pyyu36 pyyu39 pyyu38
pyyu41 pyyu44 pyyu43
pyyu46 pyyu49 pyyu48

对于awk而言,变量分为

  • 内置变量
  • 自定义变量
内置变量解释
FS输入字段分割符,默认为空白字符
OFS输出字段分隔符(输入换行符),指定输入时的换行符
ORS输出记录分隔符(输出换行符),输出时用指定符号代替换行符
NFNF:(number of field),当前行的字段的个数(即当前行被分割成了几列),字段数量
NRNR:行号,当前处理的文本行的行号
FNRFNR:各文件分别计数的行号
FILENAMEFILENAME:当前文件名
ARGCARGC:命令行参数的个数
ARGVARGV:数组,保存的是命令行所给定的各参数
[root@kvm01 ~]# awk -v FS=":" -v OFS="--" '{print NR,NF,$1}' shadow.txt
1--9--root
2--9--bin
3--9--daemon
4--9--adm
5--9--lp
6--9--sync
7--9--shutdown
8--9--halt
9--9--mail
10--9--operator
11--9--games
12--9--ftp
13--9--nobody
14--9--systemd-network
15--9--dbus
16--9--polkitd
17--9--sshd
18--9--postfix
19--9--chrony
20--9--hsqldb
21--9--mysql
NR、NF、FNR
  • awk的内置变量NR、NF是不用添加$符号的
  • $0 $1 $2 $3 ...取出每个字段的数量是需要添加$符号的

输出每行的行号,以及字段总个数

# 为处理输出的文本添加分隔符默认为空白字符(-v FS=":")
# 并输出每行的第一个字段'(print NR,$1)'
# 输出每行的分隔字段的数量'(print NR,NF,$1)'
[root@kvm01 ~]# awk -v FS=":" '{print NR,NF,$1}' shadow.txt 
1 9 root
2 9 bin
3 9 daemon
4 9 adm
5 9 lp
6 9 sync
7 9 shutdown
8 9 halt
9 9 mail
10 9 operator
11 9 games
12 9 ftp
13 9 nobody
14 9 systemd-network
15 9 dbus
16 9 polkitd
17 9 sshd
18 9 postfix
19 9 chrony
20 9 hsqldb
21 9 mysql
  • 输出每行行号,以及指定的列
# 为处理输出的文本添加分隔符默认为空白字符(-v FS=":")
# 输出每行的第一个字段'(print NR,$1)'
# 输出每行的第一个字段'(print NR,$1)'并输出每行的字段个数的倒数第二列[默认不输出]{print NR,$1,$(NF-1)}'
[root@kvm01 ~]# awk -v FS=":" '{print NR,$1,$(NF-1)}' shadow.txt 
1 root 
2 bin 
3 daemon 
4 adm 
5 lp 
6 sync 
7 shutdown 
8 halt 
9 mail 
10 operator 
11 games 
12 ftp 
13 nobody 
14 systemd-network 
15 dbus 
16 polkitd 
17 sshd 
18 postfix 
19 chrony 
20 hsqldb 
21 mysql 

# 为处理输出的文本添加分隔符默认为空白字符(-v FS=":")
# 并输出每行的第一个字段(print NR,$1)并显示每行的行号(print NR,$1,$NF)
[root@kvm01 ~]# awk -v FS=":" '{print NR,$1,$NF}' shadow.txt        
1 root 
2 bin 
3 daemon 
4 adm 
5 lp 
6 sync 
7 shutdown 
8 halt 
9 mail 
10 operator 
11 games 
12 ftp 
13 nobody 
14 systemd-network 
15 dbus 
16 polkitd 
17 sshd 
18 postfix 
19 chrony 
20 hsqldb 
21 mysql 
  • 处理多个文件并显示行号
# 如果使用NR和$0会将两个文件所有的内容合并到一起显示行号
[root@kvm01 ~]# awk '{print NR,$0}' awk.txt luffycity.txt 
1 pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
2 pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
3 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
4 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
5 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
6 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
7 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
8 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
9 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
10 pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
11 His name is chaoge.
12 I teach Linux.
13 My linux is good.
14 I like linux.
15 I like linux very much.
16 My telphone is 00000000
17 His qq is 88888888.
18 His website is http://pythonav.cn.

# 这里使用'{print FNR,$0}'就可以将两个不同的文件分别显示行号
[root@kvm01 ~]# awk '{print FNR,$0}' awk.txt luffycity.txt 
1 pyyu1  pyyu2  pyyu3  pyyu4  pyyu5
2 pyyu6  pyyu7  pyyu8  pyyu9  pyyu10
3 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
4 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
5 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
6 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
7 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
8 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
9 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
10 pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
1 His name is chaoge.
2 I teach Linux.
3 My linux is good.
4 I like linux.
5 I like linux very much.
6 My telphone is 00000000
7 His qq is 88888888.
8 His website is http://pythonav.cn.
  • 内置变量RS
# 内置变量RS:
- RS变量的作用是`输入分割符`,默认是`回车符`,也就是`回车[Enter键]换行符`
- 我们也可以自定义`空格`作为`行分隔符`,每遇见一个空格,就换行处理
# 重新写入一份实验文件
[root@kvm01 ~]# cat <<EOF >awk.txt 
pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
EOF

# 使用RS这一内置变量,让每个字段各分为一行
[root@kvm01 ~]# awk -v RS=' ' '{print NR,$0}' awk.txt
1 pyyu1
2 pyyu2
3 pyyu3
4 pyyu4
5 pyyu5
pyyu6
6 pyyu7
7 pyyu8
8 pyyu9
9 pyyu10
pyyu11
10 pyyu12
11 pyyu13
12 pyyu14
13 pyyu15
pyyu16
14 pyyu17
15 pyyu18
16 pyyu19
17 pyyu20
pyyu21
18 pyyu22
19 pyyu23
20 pyyu24
21 pyyu25
pyyu26
22 pyyu27
23 pyyu28
24 pyyu29
25 pyyu30
pyyu31
26 pyyu32
27 pyyu33
28 pyyu34
29 pyyu35
pyyu36
30 pyyu37
31 pyyu38
32 pyyu39
33 pyyu40
pyyu41
34 pyyu42
35 pyyu43
36 pyyu44
37 pyyu45
pyyu46
38 pyyu47
39 pyyu48
40 pyyu49
41 pyyu50
  • 内置变量ORS
# 内置变量ORS
- ORS是输出分隔符的意思,awk默认认为,每一行结束了,就得添加`回车换行符`
- ORS变量可以更改输出符
# 自定义'----'为回车换行符,awk在检测到了'----'之后会默认为一行进行换行
[root@kvm01 ~]# awk -v ORS="----" '{print NR,$0}' awk.txt
1 pyyu1 pyyu2 pyyu3 pyyu4 pyyu5----2 pyyu6 pyyu7 pyyu8 pyyu9 pyyu10----3 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15----4 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20----5 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25----6 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30----7 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35----8 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40----9 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45----10 pyyu46 pyyu47 pyyu48 pyyu49 pyyu50----
  • 内置FILENAME
# 内置FILENAME
- 显示awk正在处理文件的名字
[root@kvm01 ~]# awk '{print FILENAME,$0}' awk.txt 
awk.txt pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
awk.txt pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
awk.txt pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
awk.txt pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
awk.txt pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
awk.txt pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
awk.txt pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
awk.txt pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
awk.txt pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
awk.txt pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
  • 变量ARGC、ARGV
# 变量 ARGC、ARGV
- ARGV表示的是一个数组,数组中保存的是命令行所给的`参数`
- 数组是一种数据类型,如同一个盒子
- 盒子有它的名字,且内部有N个小格子,标号从0开始
- 给一个盒子起名字叫做moths,月份是1~12,如图所示

在这里插入图片描述

# 打印第二行的所有字段
[root@kvm01 ~]# awk 'NR==2{print $0}' awk.txt 
pyyu6 pyyu7 pyyu8 pyyu9 pyyu10

# 设置打印模式(BEGIN)
# 在输出某个字段之前开始输出一句话,然后再执行awk对文件的处理
[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"} {print $0}' awk.txt     
开始使用awk啦
pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
pyyu46 pyyu47 pyyu48 pyyu49 pyyu50


# 使用'ARGV'传递参数的内容作为一个变量
[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"} {print ARGV[0],$0}' awk.txt   
开始使用awk啦
awk pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
awk pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
awk pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
awk pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
awk pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
awk pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
awk pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
awk pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
awk pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
awk pyyu46 pyyu47 pyyu48 pyyu49 pyyu50

[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"} {print ARGV[1],$0}' awk.txt 
开始使用awk啦
awk.txt pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
awk.txt pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
awk.txt pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
awk.txt pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
awk.txt pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
awk.txt pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
awk.txt pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
awk.txt pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
awk.txt pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
awk.txt pyyu46 pyyu47 pyyu48 pyyu49 pyyu50

[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"} {print ARGV[2],$0}' awk.txt  
开始使用awk啦
 pyyu1 pyyu2 pyyu3 pyyu4 pyyu5
 pyyu6 pyyu7 pyyu8 pyyu9 pyyu10
 pyyu11 pyyu12 pyyu13 pyyu14 pyyu15
 pyyu16 pyyu17 pyyu18 pyyu19 pyyu20
 pyyu21 pyyu22 pyyu23 pyyu24 pyyu25
 pyyu26 pyyu27 pyyu28 pyyu29 pyyu30
 pyyu31 pyyu32 pyyu33 pyyu34 pyyu35
 pyyu36 pyyu37 pyyu38 pyyu39 pyyu40
 pyyu41 pyyu42 pyyu43 pyyu44 pyyu45
 pyyu46 pyyu47 pyyu48 pyyu49 pyyu50
 
 # 不传递任何的参数变量,只是先执行输出一句话
[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"}' awk.txt 
开始使用awk啦

[root@kvm01 ~]# awk 'BEGIN{print "开始使用awk啦"} {print ARGV[0],ARGV[1],ARGV[2]}' awk.txt shadow.txt 
开始使用awk啦
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk awk.txt shadow.txt
awk自定义变量

自定义变量:

方法一: -v varName=value

方法二: 在程序中直接定义

# 方法一: 定义一个值为变量,在awk的BEGIN模式中打印
[root@kvm01 ~]# awk -v myname="grj" 'BEGIN{print "我的名字是?",myname}'
我的名字是? grj

# 方法二: 间接引用shell变量
# 在Linux中定义一个变量,然后使用awk在BEGIN模式中输出
[root@kvm01 ~]# myname="Hello"
[root@kvm01 ~]# echo $myname
Hello
[root@kvm01 ~]# awk -v awk_name=$myname 'BEGIN{print awk_name}'
Hello
🍔awk格式化输出

printf和printf的区别:

format的使用

  • ①.与print命令最大的不同时,printf需要指定format;
  • ②.format用于指定后面的每个item的输出格式;
  • ③.printf语句不会自动打印换行符; \ \n
# format格式指示符:
- `%c`:显示字符的ASCII码
- `%d`:显示十进制整数
- `%e`,`%E`:科学计数法显示数值
- `%f`:显示浮点数
- `%g`,`%G`:以科学计数法的格式或浮点数的格式显示数值\
- `%s`:显示字符串
- `%u`:无符号整数
- `%%`:显示%自身

# printf修饰符:
- -:左对齐;默认是右对齐
- +:显示数值符号; printf "%+"
# printf动作默认不会添加换行符
# print 默认添加空格换行符
[root@kvm01 ~]# awk '{print $1}' awk.txt                
你好
你好
你好
你好
你好
你好

[root@kvm01 ~]# awk '{printf $1}' awk.txt 
你好你好你好你好你好你好[root@kvm01 ~]# 

给printf添加格式

  • 格式化字符串%s代表字符串的意思
[root@kvm01 ~]# awk '{printf "%s\n",$1}' awk.txt 
你好
你好
你好
你好
你好
你好

[root@kvm01 ~]# printf "%s" a b c d e
abcde[root@kvm01 ~]# 

[root@kvm01 ~]# printf "%s\n" a b c d e
a
b
c
d
e
[root@kvm01 ~]# printf "%s--\n" a b c d e
a--
b--
c--
d--
e--

# 使用awk的BEGIN模式换行打印输出字符串
[root@kvm01 ~]# awk 'BEGIN{printf "%d\n%d\n%d\n%d\n",1,2,3,4}'
1
2
3
4

# 为字符串输出换行
[root@kvm01 ~]# awk '{printf "第一列:%s   第二列:%s   第三列:%s\n",$1,$2,$3}' awk.txt 
第一列:正则表达式   第二列:正则表达式   第三列:正则表达式
第一列:正则表达式   第二列:正则表达式   第三列:正则表达式
第一列:正则表达式   第二列:正则表达式   第三列:正则表达式

/etc/passwd文件格式化排列输出

[root@kvm01 ~]# awk -F ":" 'BEGIN{printf "%-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\n","用户名","密码","UID","GID","用户注释","家目录的解释器","用户使用的解释器"} {printf "%-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\t  %-25s\n",$1,$2,$3,$4,$5,$6,$7}' passwd.txt    
用户名                            密码                            UID                             GID                             用户注释                              家目录的解释器                          用户使用的解释器                 
root                              x                               0                               0                               root                          /root                           /bin/bash                
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            
sync                              x                               5                               0                               sync                          /sbin                           /bin/sync                
shutdown                          x                               6                               0                               shutdown                      /sbin                           /sbin/shutdown           
halt                              x                               7                               0                               halt                          /sbin                           /sbin/halt               
mail                              x                               8                               12                              mail                          /var/spool/mail                 /sbin/nologin            
operator                          x                               11                              0                               operator                      /root                           /sbin/nologin            
games                             x                               12                              100                             games                         /usr/games                      /sbin/nologin            
ftp                               x                               14                              50                              FTP User                      /var/ftp                        /sbin/nologin            
nobody                            x                               99                              99                              Nobody                        /                               /sbin/nologin            
systemd-network                   x                               192                             192                             systemd Network Management    /                               /sbin/nologin            
dbus                              x                               81                              81                              System message bus            /                               /sbin/nologin            
polkitd                           x                               999                             998                             User for polkitd              /                               /sbin/nologin            
sshd                              x                               74                              74                              Privilege-separated SSH       /var/empty/sshd                 /sbin/nologin            
postfix                           x                               89                              89                                                            /var/spool/postfix              /sbin/nologin            
nginx                             x                               998                             996                             nginx user                    /var/cache/nginx                /sbin/nologin            
apache                            x                               48                              48                              Apache                        /usr/share/httpd                /sbin/nologin            
mysql                             x                               27                              27                              MySQL Server                  /var/lib/mysql                  /bin/false               
ntp                               x                               38                              38                                                            /etc/ntp                        /sbin/nologin            
www                               x                               1000                            1000                                                          /home/www                       /sbin/nologin            
🍕awk模式

awk模式pattern:

首先我们在这里回顾以下awk的语法

awk [option] 'pattern[action]' file ...
  • BEGIN是处理文本前,先执行BEGIN模式指定的动作
  • 再看 END的作用(awk处理完所有指定的文本后,需要执行的动作)

在这里插入图片描述

在这里插入图片描述

awk模式pattern详解

# 打印的二行的所有字段(内容)
[root@kvm01 ~]# cat -n awk.txt 
     1  正则表达式 正则表达式 正则表达式
     2  床前明月光 床前明月光 床前明月光 
     3  正则表达式 正则表达式 正则表达式

[root@kvm01 ~]# awk -n 'NR==2{print $0}' awk.txt 
床前明月光 床前明月光 床前明月光

# 打印前三行的内容
[root@kvm01 ~]# awk 'NR<4{print $0}' awk.txt 
正则表达式 正则表达式 正则表达式
床前明月光 床前明月光 床前明月光
正则表达式 正则表达式 正则表达式
关系运算符解释实例
<小于x<y
<=小于等于x<=y
==等于x==y
!=不等于x!=y
>=大于等于x>y
~匹配正则x~/正则/
!~不匹配正则x!~/正则/
# 输出行号不等于3的内容
[root@kvm01 ~]# awk 'NR!=3{print $0}' awk.txt 
正则表达式 正则表达式 正则表达式
床前明月光 床前明月光 床前明月光
  • 空模式

没有指定任何的模式(条件),因此每一行都执行了对应的动作,空模式会匹配文档的每一行,每一行都满足了(空模式)

[root@kvm01 ~]# awk '{print $1}' awk.txt 
正则表达式
床前明月光
正则表达式
  • 关系运算符模式

使用关系运算符输出指定的行

[root@kvm01 ~]# awk 'NR==2,NR==5' awk.txt 
床前明月光 床前明月光 床前明月光
正则表达式 正则表达式 正则表达式
举头望明月 举头望明月 举头望明月
正则表达式 正则表达式 正则表达式

[root@kvm01 ~]# awk 'NR==2,NR==4{print $0}' awk.txt 
床前明月光 床前明月光 床前明月光
正则表达式 正则表达式 正则表达式
举头望明月 举头望明月 举头望明月

[root@kvm01 ~]# awk 'BEGIN{print "awk的BEGIN模式输出的文本"}END{print "awk的END模式输出的文本"}' awk.txt 
awk的BEGIN模式输出的文本
awk的END模式输出的文本
awk与正则表达式

awk & 正则表达式:

正则表达式主要与awk的pattern模式(条件)结合使用

  • 不指定模式,awk每一行都会执行相应的动作

指定了模式,只有被模式匹配到的、符合条件的行才会执行的动作

找到passwd文件中具有sync的行

# 使用grep可以精准的查找出带有sync的行
[root@kvm01 ~]# cat passwd.txt | grep ^syn.*
sync:x:5:0:sync:/sbin:/bin/sync

# 使用awk匹配带有sync的行
[root@kvm01 ~]# awk '/^sync/{print $0}' passwd.txt 
sync:x:5:0:sync:/sbin:/bin/sync

# 在继续使用-F参数指定分隔符分割出每个字段,然后输出第一个字段和最后一个字段
[root@kvm01 ~]# awk -F ":" '/^sync/{print $1,$NF}' passwd.txt 
sync /bin/sync

# 
[root@kvm01 ~]# awk -F ":" 'BEGIN{printf "%-30s%-30s%-30s%-30s\n","用户名","用户ID","用户家目录","用户解释器"} {printf "%30s\t%30s\t%30s\t%30s\t\n",$1,$3,$6,$7}' passwd.txt
用户名                           用户ID                          用户家目录                         用户解释器                         
                          root                               0                           /root                       /bin/bash
                           bin                               1                            /bin                   /sbin/nologin
                        daemon                               2                           /sbin                   /sbin/nologin
                           adm                               3                        /var/adm                   /sbin/nologin
                            lp                               4                  /var/spool/lpd                   /sbin/nologin
                          sync                               5                           /sbin                       /bin/sync
                      shutdown                               6                           /sbin                  /sbin/shutdown
                          halt                               7                           /sbin                      /sbin/halt
                          mail                               8                 /var/spool/mail                   /sbin/nologin
                      operator                              11                           /root                   /sbin/nologin
                         games                              12                      /usr/games                   /sbin/nologin
                           ftp                              14                        /var/ftp                   /sbin/nologin
                        nobody                              99                               /                   /sbin/nologin
               systemd-network                             192                               /                   /sbin/nologin
                          dbus                              81                               /                   /sbin/nologin
                       polkitd                             999                               /                   /sbin/nologin
                          sshd                              74                 /var/empty/sshd                   /sbin/nologin
                       postfix                              89              /var/spool/postfix                   /sbin/nologin
                         nginx                             998                /var/cache/nginx                   /sbin/nologin
                        apache                              48                /usr/share/httpd                   /sbin/nologin
                         mysql                              27                  /var/lib/mysql                      /bin/false
                           ntp                              38                        /etc/ntp                   /sbin/nologin
                           www                            1000                       /home/www                   /sbin/nologin
awk命令执行流程

解读需求:

从pwd.txt文件中寻找我们想要的信息,按照以下顺序执行

awk 'BEGIN{command} pattern{command} END{commands}'

①.优先执行BEGIN{}模式中的语句

②.从pwd文件中读取第一行然后执行pattern{commands}进行正则匹配/^n/寻找n开头的行,找到了执行{print}进行打印

③.当awk读取到文件数据流结尾时,会执行END(commands)

  • 找出文件中禁止登录的用户

正则表达式中如果出现了"/"则需要进行转义

找出/etc/passwd文件中禁止登录的用户(/sbin/nologin)


  • 使用grep找出
[root@kvm01 ~]# grep 'nologin' /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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
www:x:1000:1000::/home/www:/sbin/nologin
  • 使用awk/\正则表达式匹配我们想要查找的条目
[root@kvm01 ~]# awk '/\/sbin\/nologin/{print $0}' /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
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
www:x:1000:1000::/home/www:/sbin/nologin

# 过滤完信息后输出行号
[root@kvm01 ~]# awk '/\/sbin\/nologin$/{print NR,$0}' /etc/passwd
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
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:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19 nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
20 apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
22 ntp:x:38:38::/etc/ntp:/sbin/nologin
23 www:x:1000:1000::/home/www:/sbin/nologin
  • 匹配从daemonntp这个区间的行并输出
[root@kvm01 ~]# awk '/^daemon/,/^ntp/{print NR,$0}' /etc/passwd
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:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
17 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
18 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19 nginx:x:998:996:nginx user:/var/cache/nginx:/sbin/nologin
20 apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
21 mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false
22 ntp:x:38:38::/etc/ntp:/sbin/nologin
  • 企业级实战: 抓取NGINX的访问日志
# 统计访问的IP地址数量:
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224
192.168.39.2
192.168.1.123
192.168.1.123
192.168.1.123
192.168.39.1
192.168.39.1
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
--- ---

# 对访问的IP地址进行去重
# 先使用 sort -n 对IP地址进行排序,拍完序后会将重复的IP地址排列到一起
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
192.168.1.123
--- ---

# 使用uniq命令进行去重查找
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq
192.168.1.123
192.168.39.1
192.168.39.2

# 最后使用wc -l查出IP行数
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq | wc -l
3

# 查看访问最频繁的前10个IP
# 对数据对应的IP字段进行查找,朝招之后去重排列,最后使用uniq -c进行输出字段次数的统计
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq -c
    300 192.168.1.123
      2 192.168.39.1
      6 192.168.39.2
      
# 将访问量从小到大排列输出
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq -c | sort -n
      2 192.168.39.1
      6 192.168.39.2
    300 192.168.1.123
    
# 加上-r的参数从大到小排序
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq -c | sort -nr
    300 192.168.1.123
      6 192.168.39.2
      2 192.168.39.1
      
# 使用head -2,抓取出NGINX访问前2的访客IP
[root@kvm01 nginx]# awk '{print $1}' /var/log/nginx/access.log-20221224 | sort -n | uniq -c | sort -nr | head -2
    300 192.168.1.123
      6 192.168.39.2
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值