一、正则表达式概述
1. 什么是正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
2.什么要使用正则表达式
在工作中,我们时刻面对着大量的日志,程序,以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串。比如: 现在有一个上千行的文件,我们仅需要其中以”root”开头的行,怎么办? 此时就需要使用到正则表达式的规则来筛选想要的内容。

二、正则表达式规则
1.常见通配符及特殊符号介绍
| 符号 | 描述 |
| . | 当前目录 |
| .. | 当前目录的上一级目录 |
| – | 当前目录的上一次所在的目录 |
| ~ | 家目录 |
| # | 注释,注释后面的命令不会被执行,超级管理员的命令提示符 |
| $ | 引用变量,数组,普通用户命令提示符 |
| ! | 非,取反 |
| & | 将程序放到后台运行 |
| && | 前面的命令执行成功,才会执行后面的命令 |
| || | 前面的命令执行失败,才会执行后面的命令 |
| | | 管道符,将前面的命令的输出结果以标准输入的方式给后面的命令 |
| \ | 转义字符,取消一些特殊字符的含义,换行,一条命令分割多行书写 |
| $()或“ | 优先执行里面的命令,将命令的执行结果输出给外面的命令 |
| * | 所有,任意 |
| ? | 匹配任意一个字符且只能是一个,必须是一个 |
| [] | 匹配中任意一个字符 |
| [^]排除中括号中任意一个字符 | |
| {} | 生成序列,整体 |
| () | 整体 |
| ” | 单引号,强引用 |
| “” | 双引号,弱引用 |
| ; | 命令的分隔符 |
2.基础正则表达式
| 符号 | 描述 |
| ^ | 以什么为开头 |
| $ | 以什么结尾 |
| ^$ | 空行 |
| . | 任意一个字符,排除换行符 |
| * | 匹配前面的字符出现0次或者多次 |
| .* | 所有 |
| \ | 转义字符,将一些特殊的字符取消特殊的含义 |
| [] | 匹配中括号中任意一个字符 |
| [^] | 排除中括号中任意一个字符 |
| [0-9] | 所有数字 |
| [a-Z] | 所有字母 |
3.扩展正则
| 符号 | 描述 |
| + | 匹配前面的字符出现1次或者多次 |
| ? | 匹配前面的字符出现0次或者1次 |
| | | 或者 |
| () | 创建一个用户匹配的字符串,后向引用 |
| {n} | n=数字,匹配前面的字符出现n次 |
| {n,} | 匹配前面的字符至少出现n次,最大没有限制 |
| {n,m} | 匹配前面的字符出现至少n次,最大m次(n |
| {,m} | 匹配前面的字符至少出现0次,最多m次 |
4.特殊字符
| 符号 | 描述 |
| [[:upper:]] | 所有大写字母 |
| [[:lower:]] | 所有小写字母 |
| [[:alpha:]] | 所有字母 |
| [[:digit:]] | 所有数字 |
| [[:alnum:]] | 所有数字和字母 |
| [[:space:]] | 空白字符 |
| [[:punct:]] | 所有特殊字符 标点符号 |
三、正则表达式之Grep文本过滤实例
#以root开头
[root@xian /server/scripts]# grep '^root' passwd
root:x:0:0:root:/root:/bin/bash
#以h结尾
[root@xian /server/scripts]# grep 'h$' passwd
root:x:0:0:root:/root:/bin/bash
aaa5:x:1001:1001::/home/aaa5:/bin/bash
#匹配空行并显示行号
[root@xian /server/scripts]# grep -n '^$' passwd
27:
28:
#匹配所有行,包括字符
[root@xian /server/scripts]# grep -n '.*' passwd
。。。
。。。
。。。
24:mysql:x:27:27:MariaDB Server:/var/lib/mysql:/sbin/nologin
25:nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
26:aaa5:x:1001:1001::/home/aaa5:/bin/bash
27:
28:
#过滤所有空白字符
[root@xian /server/scripts]# grep -n '^[[:space:]]*$' passwd
27:
28:
#过滤所有特殊符合或者标点符号 (如 / $ % @ & ^ * ! . , :等 )
[root@xian /server/scripts]# grep '[[:punct:]]' passwd
root:x:0:0:root:/root:/b!in/bash
bin:x:1$:1:bin:/bin:/sb@in/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/l&&,pd:/sbin/nologin
sync:x:5:0:sync:/sbin:/b*in./sync
shutdown:x:6:0:shutdow#n:/sb/in:/sbin/shutdown
#匹配以a或者b开头的行
[root@xian /server/scripts]# grep -E '^[ab]' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
aaa5:x:1001:1001::/home/aaa5:/bin/bash
#统计文件中所有字母出现的次数,自出从大到小进行排列
[root@xian /server/scripts]# grep -o '[a-Z]' passwd |sort |uniq -c | sort -nr |head
103 n
82 o
75 i
70 s
50 b
45 a
43 l
41 r
37 e
32 t
#统计文件中所有单词出现的次数,次数从大到小进行排列
[root@xian /server/scripts]# egrep -o '[a-Z]+' passwd |sort |uniq -c |sort -nr |head
27 sbin
26 x
21 nologin
11 var
6 bin
5 lib
4 User
4 root
3 sync
3 spool
[root@xian /server/scripts]# grep -o '[a-Z]*' passwd |sort |uniq -c |sort -nr |head
27 sbin
26 x
21 nologin
11 var
6 bin
5 lib
4 User
4 root
3 sync
3 spool
#匹配字符出现0次或0次以上 (没有匹配到的行也显示出来了)
[root@xian /server/scripts]# grep 'l*' passwd
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
#匹配字符出现1次或1次以上 (只显示匹配到的行)
[root@xian /server/scripts]# grep -E 'l+' 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
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
#匹配字符出现0次或0次以上 (一个字符串中,并不是一行)
[root@xian /server/scripts]# grep -o 'o*' passwd
oo
oo
oo
o
o
o
o
oo
o
#匹配字符出现0次或1次 (一个字符串只出现0次或1次)
[root@xian /server/scripts]# grep -Eo 'o?' passwd
o
o
o
o
o
o
o
o
o
o
o
#过滤多个字符串开头的行 (或者的意思)
[root@xian /server/scripts]# grep '^nginx' passwd
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@xian /server/scripts]# grep -E '^nginx|^sync' passwd
sync:x:5:0:sync:/sbin:/bin/sync
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@xian /server/scripts]# grep -E '^(mail|nginx|sync)' passwd
sync:x:5:0:sync:/sbin:/bin/sync
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
#匹配数字出现2次
[root@xian /server/scripts]# grep -Ew '[0-9]{2}' passwd
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
#匹配数字出现4次
[root@xian /server/scripts]# grep -Ew '[0-9]{4}' passwd
aaa5:x:1001:1001::/home/aaa5:/bin/bash
#匹配数字出现最少3次最多4次
[root@xian /server/scripts]# grep -Ew '[0-9]{3,4}' passwd
games:x:12:100:games:/usr/games:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
aaa5:x:1001:1001::/home/aaa5:/bin/bash
#模拟取出正确的身份证号码(18位 且最后一位有可能是X)
[root@xian /server/scripts]# cat sfz.txt
lx 123465755343443675
lx 436456D546567F4656
lx A45476797898065776
lx 40980348594503485X
lx 3274543785674352X2
lx 93584375897589347X
lx 38947837543758342X
lx 348238493208423490
lx 23472364783657843C
[root@xian /server/scripts]# grep -Ew '[0-9X]{18}' sfz.txt
lx 123465755343443675
lx 40980348594503485X
lx 3274543785674352X2
lx 93584375897589347X
lx 38947837543758342X
lx 348238493208423490
[root@xian /server/scripts]# grep -Ew '[0-9]{17}[0-9X]{1}' sfz.txt
lx 123465755343443675
lx 40980348594503485X
lx 93584375897589347X
lx 38947837543758342X
lx 348238493208423490
四、正则表达式之Sed文本替换实例
三剑客第二 擅长取行 、增删改查
1.sed命令选项
| 选项 | 作用 |
| -n | 取消默认输出 |
| -i | 真正的修改文件 |
| -r | 支持扩展正则 |
| -e | 允许多项编辑 |
2.sed命令参数
| 命令参数 | 作用 |
| p | 打印 |
| d | 删除 |
| s | 替换 |
| g | 全局 |
| a | 追加 |
| i | 插入 |
| c | 替换,在当前行替换 |
| w | 将匹配的内容写入指定文件中 |
| i | 忽略大小写 |
3.sed命令实例操作
#打印-p参数实例 [root@xian /server/scripts]# sed -n '1p' passwd root:x:0:0:root:/root:/b!in/bash [root@xian /server/scripts]# sed -n '1,3p' passwd root:x:0:0:root:/root:/b!in/bash bin:x:1$:1:bin:/bin:/sb@in/nologin daemon:x:2:2:daemon:/%sbin:/sbin/nologin [root@xian /server/scripts]# sed -n '1p;3p' passwd root:x:0:0:root:/root:/b!in/bash daemon:x:2:2:daemon:/%sbin:/sbin/nologin [root@xian /server/scripts]# sed -n '/root/p' passwd root:x:0:0:root:/root:/b!in/bash operator:x:11:0:operator:/root:/sbin/nologin [root@xian /server/scripts]# sed -n '/root/p;/halt/p' passwd root:x:0:0:root:/root:/b!in/bash halt:x:7:0:halt:/sbin:/sbin'/halt operator:x:11:0:operator:/root:/sbin/nologin [root@xian /server/scripts]# sed -nr '/root|nginx/p' passwd root:x:0:0:root:/root:/b!in/bash operator:x:11:0:operator:/root:/sbin/nologin nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin #删除-d参数实例 [root@xian /server/scripts]# sed '1,23d' passwd [root@xian /server/scripts]# sed '1d;3d' passwd [root@xian /server/scripts]# sed '/aaa5/d' passwd [root@xian /server/scripts]# sed '/aaa5|nginx/d' passwd #替换-s g i 参数实例 g 是全局 (如果不加g,则只替换每一行的第一个符合的数据) [root@xian /server/scripts]# cat passwd root:x:0:0:root:/root:/b!in/bash [root@xian /server/scripts]# sed 's#root#lixian#' passwd lixian:x:0:0:root:/root:/b!in/bash [root@xian /server/scripts]# sed 's#root#lixian#g' passwd lixian:x:0:0:lixian:/lixian:/b!in/bash #多行替换 [root@xian /server/scripts]# sed '1,5s#root#lixian#g' passwd #替换忽略大小写 [root@xian /server/scripts]# sed '1,5s#root#lixian#gi' passwd #追加-a参数实例 #追加到第一行下面 [root@xian /server/scripts]# sed '1awohenshuai' passwd root:x:0:0:root:/root:/b!in/bash wohenshuai bin:x:1$:1:bin:/bin:/sb@in/nologin #追加多行到第一行下面 [root@xian /server/scripts]# sed '1awohen\nshuai' passwd root:x:0:0:root:/root:/b!in/bash wohen shuai bin:x:1$:1:bin:/bin:/sb@in/nologin #插入多行到第一行前面 [root@xian /server/scripts]# sed '1iwohen\nshuai' passwd wohen shuai root:x:0:0:root:/root:/b!in/bash bin:x:1$:1:bin:/bin:/sb@in/nologin #替换的方式追加到第一行行首 [root@xian /server/scripts]# sed '1s#^#lixian\n#g' passwd lixian root:x:0:0:root:/root:/b!in/bash bin:x:1$:1:bin:/bin:/sb@in/nologin #行替换-c参数实例 (相当于把第一行删了 然后写入一行内容进去替换这一行) [root@xian /server/scripts]# cat passwd root:x:0:0:root:/root:/b!in/bash bin:x:1$:1:bin:/bin:/sb@in/nologin [root@xian /server/scripts]# sed '1c lixian' passwd lixian bin:x:1$:1:bin:/bin:/sb@in/nologin #匹配bin开头的行删除并替换内容 [root@xian /server/scripts]# sed '/^bin/c lixian' passwd root:x:0:0:root:/root:/b!in/bash lixian #写入到一个文件-w参数实例 #过滤nginx和ntp的行写入到文件中 [root@xian /server/scripts]# sed -nr '/nginx|ntp/wlixian.txt' passwd [root@xian /server/scripts]# cat lixian.txt ntp:x:38:38::/etc/ntp:/sbin/nologin nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin #第十行到第十五行内容写入到一个文件内 [root@xian /server/scripts]# sed -nr '10,15wlixian.log' passwd [root@xian /server/scripts]# cat lixian.log 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
#删除没有空格和tab键的空行
[root@xian /server/scripts]# sed '/^$/d' default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
}
#删除有空格和tab键的空行
[root@xian /server/scripts]# sed '/^[ \t]*$/d' default.conf
[root@xian /server/scripts]# sed '/^\s*$/d' default.conf
#删除带有注释行、空格行、tab行
[root@xian /server/scripts]# sed -r '/^[ \t]*($|#)/d' default.conf
server {
listen 80;
server_name localhost;
}
#给所有文件内容加注释
[root@xian /server/scripts]# sed 's/^/#/g' default.conf
#server {
# listen 80;
# server_name localhost;
#
# # deny access to .htaccess files, if Apache's document root
# # concurs with nginx's one
#}
#
#将多余的#号及空格、tab符去掉
[root@xian /server/scripts]# cat default.conf
##server {
# listen 80;
## #server_name localhost;
# #
## #charset koi8-r;
# # access_log /var/log/nginx/host.access.log main;
##
## # deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
##}
[root@xian /server/scripts]# sed 's/^[ \t#]*/#/g' default.conf
#server {
#listen 80;
#server_name localhost;
#
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
#
#deny access to .htaccess files, if Apache's document root
#concurs with nginx's one
#}
五、正则表达式之Awk文本取列实例
1. Awk基本介绍
awk是一种编程语言 gawk 对于底层的操作系统的文本及数据处理
2.Awk处理数据的方式
1. 读入文件,按行进行读取,从第一行到最后一行
2. 寻找匹配的条件的行,在行上进行操作
3. 如果此行没有满足条件的,会丢弃,没有指定条件的,会把当前行内容全部打印出来
3.Awk的语法
awk [option] ‘command’ files
4.处理模式
行处理前 行处理中 行处理后
BEGIN{} {} END{}
[root@xian /server/scripts]# awk 'BEGIN{print 9-1}{print $2}END{print "命令结束"}' /etc/hosts
8
localhost
localhost
命令结束
5.Awk的工作原理
[root@xian /server/scripts]# awk -F: '{print $1,$2}' passwd
1. awk将文件中的每一行作为输入,并将每一行处理的时候放入到特定的模式空间中,将每一行的数据赋值给内部变量$0, 以换行符结束
2. awk开始进行字段分解,每个字段存储在自己的内部变量中, 变量从$1开始
3. awk默认字段分割是由内部变量FS来指定的,可以使用-F修订,默认的分割符为空白字符
4. awk行处理时使用print来打印分割后的字段
5. awk在打印之后会给不同的字段之间加上空格作为输出分隔符,这个分割符是由书写的逗号进行映射,逗号被映射到内部变量输出分隔符OFS,默认输出分隔符就是空格
6. awk输出之后,将从文件中读取下一行内容,并将其存储到$0变量中,覆盖原来的内容,然后接着进行循环处理,直到文件行处理结束
6.Awk内部变量
#使用默认输入分隔符 默认分隔符为空白字符
[root@xian /server/scripts]# awk '{print $2}' /etc/hosts
localhost
localhost
#指定分隔符
[root@xian /server/scripts]# awk -F: '{print $1}' passwd
root
bin
daemon
adm
lp
sync
[root@xian /server/scripts]# awk 'BEGIN{FS=":"}{print $1}' passwd
root
bin
daemon
adm
lp
sync
#指定多个分隔符
[root@xian /server/scripts]# ip a s eth0 | awk -F '[ /]*' 'NR==3{print $3}'
10.0.0.99
[root@xian /server/scripts]# ip a s eth0 | awk 'BEGIN{FS="[ /]*"}NR==3{print $3}'
10.0.0.99
#输出分隔符 OFS (输出分隔符默认为空格 使用逗号进行映射 )
[root@xian /server/scripts]# awk 'BEGIN{FS=":";OFS="@"}{print $1,$2}' passwd
root@x
bin@x
daemon@x
adm@x
lp@x
# -v 使用内部变量 定义awk内部变量
[root@xian /server/scripts]# awk -F: -vOFS="$" '{print $1,$2}' passwd
root$x
bin$x
daemon$x
adm$x
lp$x
[root@xian /server/scripts]# awk -vFS=":" -vOFS="$" '{print $1,$2}' passwd
root$x
bin$x
daemon$x
adm$x
lp$x
#最后一列 NF 显示最后一列的编号,显示此行有多少列 $NF 打印最后一列
[root@xian /server/scripts]# awk -F: '{print NF,$NF}' passwd
7 /bin/bash
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
7 /sbin/nologin
[root@xian /server/scripts]# awk -F: '{print $(NF-1)}' passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd
#行号 FNR 记录每个文件的行号或者编号
[root@xian /server/scripts]# awk '{print NR,$0}' passwd /etc/hosts
1 root:x:0:0:root:/root:/bin/bash
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
[root@xian /server/scripts]# awk '{print FNR,$0}' passwd /etc/hosts
1 root:x:0:0:root:/root:/bin/bash
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
#格式化输出
#使用Awk的一种方式,自定义输出
[root@xian /server/scripts]# date | awk '{print "今年是:"$NF"\t月份为:"$2}'
今年是:2020 月份为:May
7.Awk模式动作
# 正则表达式
[root@xian /server/scripts]# awk '/^root/' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk '/t$/' passwd
halt:x:7:0:halt:/sbin:/sbin/halt
[root@xian /server/scripts]# awk '!/n$/' passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
halt:x:7:0:halt:/sbin:/sbin/halt
[root@xian /server/scripts]# awk '$0 ~/^root/' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk -F: '$3 ~/0/' passwd
root:x:0:0:root:/root:/bin/bash
#比较表达式
两个数值或者字符进行比较,只有条件为真时,才会执行指定的动作
关系运算符
<
>
<=
>=
==
!=
[root@xian /server/scripts]# awk -F: '$3==0' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk -F: '$3==0{print $1}' passwd
root
[root@xian /server/scripts]# awk -F: '$3<6{print $1,$3}' passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
[root@xian /server/scripts]# awk -F: '$3>6{print $1,$3}' passwd
halt 7
mail 8
operator 11
[root@xian /server/scripts]# awk -F: '$3>=6{print $1,$3}' passwd
shutdown 6
halt 7
mail 8
operator 11
[root@xian /server/scripts]# awk -F: '$1 == "root" ' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk -F: '$1 == "root" && $3 == 0 ' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk -F: '$1 == "root" || $3 == 1 ' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@xian /server/scripts]# awk -F: '$1 != "root"' 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
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
[root@xian /server/scripts]# awk -F: '$1 ~/^r/' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk -F: '$3 ~/^1/' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
[root@xian /server/scripts]# awk -F: '$3 !~/1$/' passwd
root:x:0:0:root:/root:/bin/bash
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
[root@xian /server/scripts]# df | awk '/\/$/'
/dev/sda3 18863104 2572044 16291060 14% /
#条件表达式
[root@xian /server/scripts]# awk -F: '{if($3==0){print "管理员"$1}else{print "普通用户"$1}}' passwd
管理员root
普通用户bin
普通用户daemon
普通用户adm
普通用户lp
普通用户sync
普通用户shutdown
普通用户halt
普通用户mail
普通用户operator
[root@xian /server/scripts]# awk -F: '{if($3==0){print "管理员"$1}}' passwd
管理员root
[root@xian /server/scripts]# awk -F: '$3 == 0{print "管理员"$1}' passwd
管理员root
#运算表达式
[root@xian /server/scripts]# awk 'BEGIN{print 1 + 1}'
2
[root@xian /server/scripts]# awk -F: '$3 + 10 >15' passwd
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
[root@xian /server/scripts]# awk -F: '/mail/{print $3}' passwd
8
[root@xian /server/scripts]# awk -F: '/mail/{print $3 * 10 }' passwd
80
#逻辑操作符 复合模式
&& || !
[root@xian /server/scripts]# awk -F: '$1 == "root" && $3 == 0{print "管理员为:"$1}' passwd
管理员为:root
[root@xian /server/scripts]# awk -F: '$1 == "root" || $3 == 1{print $1}' passwd
root
bin
[root@xian /server/scripts]# awk -F: '$1 !~/^r/' 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
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
[root@xian /server/scripts]# awk 'NR==1' passwd
root:x:0:0:root:/root:/bin/bash
[root@xian /server/scripts]# awk '/root/' passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@xian /server/scripts]# awk '!/root/' 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
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
解释下面命令的作用和含义
# awk '/west/' datafile 打印所有关于west的行
# awk '/^north/' datafile 打印所有以north开头的行
# awk '$3 ~ /^north/' datafile #打印第三列中以north开头的行
# awk '/^(no|so)/' datafile #打印以no和so开头的行
# awk '{print $3,$2}' datafile #打印第三列和第二列,并且以空格分隔
# awk '{print $3 $2}' datafile #打印第三列和第二列
# awk '{print $0}' datafile #打印所有的行
# awk '{print "Number of fields: "NF}' datafile #打印文件的列数
# awk '/northeast/{print $3,$2}' datafile #打印所有northeast的行,输出第三列和第二列
# awk '/^[ns]/{print $1}' datafile #打印以ns开头的行,并且输出第一列
# awk '$5 ~ /\. [7-9]+/' datafile #打印第五列7到9的数字
# awk '$2 !~ /E/{print $1,$2}' datafile 打印第二列不匹配关于E的行的第1列和第2列
# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile #打印第三列以Joel开头输出第三列
# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile #打印第八列两位数字结尾输出第八列
# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile #打印第四列以China结尾的第八列
# awk '/Tj/{print $0}' datafile #打印所有Tj的行
# awk -F: '{print "Number of fields: "NF}' /etc/passwd # #以:为分隔符输出文件的列数
# awk -F"[ :]" '{print NF}' /etc/passwd #以:和空格为分隔符输出文件的列数
8.Awk的条件判断
if 表达式 动作
if 表达式 动作 else 动作
if 表达式 动作 else if 表达式 动作 else 动作
#打印当前系统中管理员用户
[root@xian /server/scripts]# awk -F: '{if($3==0){print $1"为系统管理员用户"}}' passwd
root为系统管理员用户
[root@xian /server/scripts]# awk -F: '{if($3>0){i++}}END{print "系统用户的数量为:"i}' /etc/passwd
系统用户的数量为:30
[root@xian /server/scripts]# awk -F: '{if($3>0 && $3<1000){i++}}END{print "系统用户的数量为:"i}' /etc/passwd
系统用户的数量为:23
[root@xian /server/scripts]# awk -F: '{if($3>=1000){i++}}END{print "普通用户的数量为:"i}' /etc/passwd
普通用户的数量为:7
[root@xian /server/scripts]# awk -F: '{if($3==0){a++}else if($3>0 && $3<1000){b++}else{c++}}END{print "管理员 数量为:"a,"系统用户数量为:"b,"普通用户数量为:"c}' /etc/passwd
管理员数量为:1 系统用户数量为:23 普通用户数量为:7
9.Awk的循环语句
#for循环
#1. 打印1-5的数字
[root@xian /server/scripts]# awk 'BEGIN{for (i=1;i<=5;i++){print i}}'
1
2
3
4
5
#创建10个用户
[root@xian /server/scripts]# awk 'BEGIN{for (i=1;i<=10;i++){print "useradd lx"i}}' | bash
#创建10个不同日期的文件
[root@xian /server/scripts]# awk 'BEGIN{for (i=1;i<=10;i++){print "date -s 2020/05/"i" &>/dev/null && touch /tmp/file-"i".txt"}}' | bash
#while 循环
#打印1-10的数字
[root@xian /server/scripts]# awk 'BEGIN{a=1;while(a<=5){print a;a++}}'
1
2
3
4
5
#创建10个用户
[root@xian /server/scripts]# awk 'BEGIN{a=1;while(a<=10){print "useradd qls"a;a++}}' | bash
#创建10个不同日期的文件
[root@xian /server/scripts]# awk 'BEGIN{a=1;while(a<=10){print "date -s 2020/05/"a" &>/dev/null && touch /tmp/file-"a".txt";a++}}' | bash
10.Awk数组
i++ #统计次数 i[$1]++
i+= #求和 i+=$1
#1.统计/etc/passwd文件中每一种shell的数量
[root@xian /server/scripts]# awk -F: '{Shells[$NF]++}END{for(i in Shells){print "Shell: "i,"Count: "Shells[i]}}' /etc/passwd
Shell: /bin/sync Count: 1
Shell: /bin/bash Count: 11
Shell: /sbin/nologin Count: 21
Shell: /sbin/halt Count: 1
Shell: /sbin/shutdown Count: 1
#2. 统计tcp11中状态
[root@xian /server/scripts]# netstat -ant | awk 'NR>2{State[$NF]++}END{for(i in State){print "State: "i,"Count: "State[i]}}'
State: LISTEN Count: 6
State: ESTABLISHED Count: 1
#3. 计算1-100之间的和
[root@xian /server/scripts]# seq 100| awk '{Sum+=$1}END{print Sum}'
5050
#4. 统计日志中的PV量 一条日志就等于一个PV
[root@xian /server/scripts]# wc -l access.log
37593 access.log
[root@xian /server/scripts]# awk '{i++}END{print i}' access.log
37593
[root@xian /server/scripts]# awk '{PV[$1]++}END{for (i in PV) {Sum+=PV[i]}{print Sum}}' access.log
37593
#5. 统计访问最多的10个IP地址
[root@xian /server/scripts]# awk '{Ips[$1]++}END{for (i in Ips)print "IP地址为: "i,"访问次数为: "Ips[i]}' access.log |sort -rnk4 | head | column -t
IP地址为: 139.226.172.217 访问次数为: 16033
IP地址为: 47.102.42.79 访问次数为: 1041
IP地址为: 180.95.238.82 访问次数为: 994
IP地址为: 113.140.249.33 访问次数为: 727
IP地址为: 223.166.74.124 访问次数为: 647
IP地址为: 112.87.125.55 访问次数为: 525
IP地址为: 182.138.163.167 访问次数为: 429
IP地址为: 112.87.125.53 访问次数为: 373
IP地址为: 223.166.74.198 访问次数为: 352
IP地址为: 182.138.158.169 访问次数为: 308
#6. 统计访问次数大于500次的IP地址
[root@xian /server/scripts]# awk '{Ips[$1]++}END{for (i in Ips){if(Ips[i]>500){print "访问次数大于100次的IP地 址为: "i,"访问次数为: "Ips[i]}}}' access.log |sort -rnk4 | column -t
访问次数大于100次的IP地址为: 139.226.172.217 访问次数为: 16033
访问次数大于100次的IP地址为: 47.102.42.79 访问次数为: 1041
访问次数大于100次的IP地址为: 180.95.238.82 访问次数为: 994
访问次数大于100次的IP地址为: 113.140.249.33 访问次数为: 727
访问次数大于100次的IP地址为: 223.166.74.124 访问次数为: 647
访问次数大于100次的IP地址为: 112.87.125.55 访问次数为: 525
[root@xian /server/scripts]# awk '{Ips[$1]++}END{for (i in Ips){if (Ips[i]>500){print i,Ips[i]}}}' access.log | sort -rnk2 | column -t
139.226.172.217 16033
47.102.42.79 1041
180.95.238.82 994
113.140.249.33 727
223.166.74.124 647
112.87.125.55 525
#7. 统计访问最多的10个URL页面 $11
[root@xian /server/scripts]# awk '{Url[$11]++}END{for(i in Url){if(Url[i]>100) {print i,Url[i]}}}' access.log |sort -rnk2|head
"-" 16062
"https://www.increase93.com/" 7284
"https://www.increase93.com/?p=116" 2000
"https://www.increase93.com/?p=193" 1805
"https://www.increase93.com/?cat=5&paged=3" 886
"https://www.increase93.com/?p=292" 847
"https://www.increase93.com/wp-content/themes/QQ2.8/style.css?ver=4.1" 714
"https://www.increase93.com/?p=131" 522
"https://www.increase93.com/?p=458" 391
"https://www.increase93.com/wp-content/themes/QQ2.8/css/font-awesome.css" 326
#8. 统计每种状态码的数量
[root@xian /server/scripts]# awk '{state[$9]++}END{for(i in state){print i,state[i]}}' access.log |sort -rnk2
200 26302
302 6108
404 2507
401 1084
304 986
499 185
206 149
400 111
150 99
301 33
504 11
405 8
SP1 4
Vezir.04 3
413 1
408 1
403 1
#9. 统计所有IP请求访问响应数据总大小 $10
[root@xian /server/scripts]# awk '{Sum+=$10}END{print Sum}' access.log
1308567366
#10. 统计每个IP地址访问的状态码的数量
[root@xian /server/scripts]# awk '{Ips_State["IP: "$1" State: "$9]++}END{for (i in Ips_State){print i,"Count: "Ips_State[i]}}' access.log | grep 139.226.172.217
IP: 139.226.172.217 State: 200 Count: 14731
IP: 139.226.172.217 State: 206 Count: 88
IP: 139.226.172.217 State: 404 Count: 193
IP: 139.226.172.217 State: 499 Count: 99
IP: 139.226.172.217 State: 302 Count: 108
IP: 139.226.172.217 State: 304 Count: 805
IP: 139.226.172.217 State: 504 Count: 9
#11. 统计每个IP地址的服务端响应的总字节大小及次数
[root@xian /server/scripts]# awk '{Ips[$1]++;Sum[$1]+=$10}END{for (i in Ips){print "IP: "i,"Count: "Ips[i],"Size: "Sum[i]}}' access.log | sort -rnk4 | head | column -t
IP: 139.226.172.217 Count: 16033 Size: 749869585
IP: 47.102.42.79 Count: 1041 Size: 16462
IP: 180.95.238.82 Count: 994 Size: 154136
IP: 113.140.249.33 Count: 727 Size: 105270
IP: 223.166.74.124 Count: 647 Size: 93670
IP: 112.87.125.55 Count: 525 Size: 15640394
IP: 182.138.163.167 Count: 429 Size: 62205
IP: 112.87.125.53 Count: 373 Size: 10792077
IP: 223.166.74.198 Count: 352 Size: 61217
IP: 182.138.158.169 Count: 308 Size: 44660
#12. 统计每个IP地址访问URL页面的服务端响应的总字节大小及次数
[root@xian /server/scripts]# awk '(sum+=$10){print sum}' access.log |tail -n1
1308567366
#13. 统计状态码为200的次数
[root@xian /server/scripts]# awk '{state[$9]++}END{for(i in state){print i,state[i]}}' access.log |sort -rnk2|grep 200
200 26302

