一、正则表达式概述
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