1. 正则表达式概述

01. 什么是正则表达式

正则表达式regular expression, RE是一种字符模式,用于在查找过程中匹配指定的字符。

02. 为什么要使用正则表达式?

在工作中,我们时刻面对着大量的日志,程序,以及命令的输出。迫切的需要过滤我们需要的一部分内容,甚至是一个字符串。比如: 现在有一个上千行的文件,我们仅需要其中包含"root"的行,怎么办? 此时就需要使用到正则表达式的规则来筛选想要的内容。



03. 正则表达式注意事项

1.正则表达式应用非常广泛,存在于各种语言中,例如:php,python,java等。2.正则表达式和通配符特殊字符是有本质区别的3.要想学好grep、sed、awk首先就要掌握正则表达式。4.注意正则神坑,中文符号。

2. 正则表达式规则

正则表达式          描述

\            转义符,将特殊字符进行转义,忽略其特殊意义

^            匹配行首,^是匹配字符串的开始

$            匹配行尾,$是匹配字符串的结尾

^			$表示空行.

(点)			匹配换行符之外的任意单个字符

[ ]			匹配包含在[字符]之中的任意一个字符

[^]			匹配[^]之外的任意一个字符

[a-z]		匹配[]中指定范围内的任意一个字符

?			匹配其前面的字符1次或者0次+匹配其前面的字符1次或者多次  匹配其前面的字符0次或者多次**.**

*			表示所有( )匹配表达式,创建一个用于匹配的字符串

{n}			匹配之前的项n次,n是可以为0的正整数{n,}之前的项至少需要匹配n次

{n,m}		指定之前的项至少匹配n次,最多匹配m次,n<=m
| 或者 特定字符含义 [[:upper:]] 所有大写字母 [[:lower:]] 所有小写字母 [[:alpha:]] 所有字母 [[:digit:]] 所有数字 [[:alnum:]] 所有的字母和数字 [[:space:]] 空白字符,空白。 [[:punct:]] 所有标点符号

3. 正则表达式之GREP文本过滤

环境准备

环境准备
[root@gjy ~]# cat test.txt
I am qiuzengjia teacher!
I teach linux.
test I like badminton ball ,billiard ball and chinese chess!
my blog is http://www.oldboyedu.blog.com
our site is http://www.increase93.com
my qq num is 1176495252.
not 117666649555252.

正则

#过滤以m开头的行
[root@gjy ~]# grep "^m" test.txt
#过滤以m为结尾的行
[root@gjy ~]# grep "m$" test.txt
#排除空行, 并打印行号
[root@gjy ~]# grep -vn "^$" test.txt
#匹配任意一个字符,不包括空行
[root@gjy ~]# grep "." test.txt
#匹配所有内容
[root@gjy ~]# grep ".*" test.txt
#过滤出以.为结尾的行
[root@gjy ~]# grep "\.$" test.txt
#过滤出以m和n为开头的行
[root@gjy ~]# grep "^[mn]" test.txt
#过滤出文件中不是以m或n或o开始的行
[root@gjy ~]# egrep "^[^mno]" test.txt
[root@gjy ~]# egrep -v "^[mno]" test.txt
#过滤出空行,并显示行号
[root@gjy ~]# grep -n "^$" test.txt
#把文件中每个字母总共出现多少次统计出
[root@gjy ~]# grep -o "[a-Z]" test.txt |sort |uniq -c|sort -rh
#把文件中每个单词总共出现多少次统计出
[root@gjy ~]# egrep -o "[a-Z]+" test.txt |sort |uniq -c|sort -rh
#找出/etc/passwd文件中的两位数或三位数的行;
[root@gjy ~]# grep -Ew "[0-9]{2,3}" /etc/passwd
#找出/proc/meminfo文件中,所有大写或小写s开头的行;至少有三种实现方式;
[root@gjy ~]# grep "^[sS]" /proc/meminfo
[root@gjy ~]# grep -i "^s" /proc/meminfo
[root@gjy ~]# grep -E "^(s|S)" /proc/meminfo
#显示当前系统上root、CentOS或user1用户的相关信息;
[root@gjy ~]# grep -E "^(root|CentOS|user1)"
/etc/passwd #找出/etc/init.d/functions文件中某单词后跟一个小括号的行;
[root@gjy ~]# grep -E -o "^[_[:alnum:]]+\(\)" /etc/init.d/functions
#环境准备
[root@gjy ~]# cat id.txt
邹 371481199403259478
莫 52020319810613433X
韩 46010619911113727A
荣 53012419750413543
荣 530124197504135438
阮 360702197902169951
任 6212231987082X5176
姜 370602198507189574
赵 BBB602198507189574
#找出正确的身份证号码
[root@gjy ~]# egrep "[0-9]{17}[0-9X]" id.txt

4. 正则表达式之SED文本处理

Sed是一个流编辑器, 非交互式的编辑器,它一次处理一行内容. 处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space)
接着用Sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
文件内容并没有改变,除非你使用重定向存储输出。
Sed是用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

01. Sed命令格式

sed [options] 'command' file(s)
Sed正则使用与Grep一样,Sed在文件中查找模式时也可以使用正则表达式(RE)和各种元字符。
正则表达式是括在斜杠间的模式,用于查找和替换,以下是sed支持的元字符。
使用基本元字符集 ^, $, ., *, [], [^], < >, (), {} 使用扩展元字符集 ?, +, { }, |, ( )
使用扩展元字符的方式 + sed -r

02. Sed命令示例

Sed对指定行进行操作,包括打印、删除、修改、追加等。
Sed选项参数-e
#允许多项编辑-n
#取消默认的输出-i
#直接修改对应文件-r
#支持扩展元字符Sed命令参数a
#在当前行后添加一行或多行c
#在当前行进行替换修改d
#在当前行进行删除操作i
#在当前行之前插入文本p
#打印匹配的行或指定行n
#读入下一输入行,从下一条命令进行处理!
#对所选行以外的所有行应用命令h
#把模式空间里的内容重定向到暂存缓冲区H
#把模式空间里的内容追加到暂存缓冲区g
#取出暂存缓冲区的内容,将其复制到模式空间,覆盖该处原有内容G
#取出暂存缓冲区的内容,将其复制到模式空间,追加在原有内容后面

多重编辑选项 e

#先删除行,然后管道给后面的sed进行替换
[root@gjy ~]# sed '1,9d' passwd |sed 's#root#gjy#g'
#使用-e进行多次编辑修改操作
[root@gjy ~]# sed -e '1,9d' -e 's#root#gjy#g' passwd

打印命令p

g#打印匹配halt的行
[root@gjy ~]# sed -n '/halt/p' passwd
halt:x:7:0:halt:/sbin:/sbin/halt
#打印第二行的内容
[root@gjy ~]# sed -n '2p' passwd
bin:x:1:1:bin:/bin:/sbin/nologin
#打印最后一行
[root@gjy ~]# sed -n '$p' passwd
**追加命令a** #给30行添加配置 \t tab键(需要转义) \n 换行符
[root@gjy ~]# sed -i '30a listen 80;' passwd

追加命令a

给30行添加配置 \t tab键(需要转义) \n 换行符
[root@gjy ~]# sed -i '30a listen 80;' passwd

修改命令c

#指定某行进行内容替换
[root@gjy ~]# sed -i '7c SELINUX=Disabled' /etc/selinux/config
#正则匹配对应内容, 然后进行替换
sed -i '/^SELINUX=/cSELINUX=Disabled' /etc/selinux/config
#非交互式修改指定的配置文件
[root@gjy ~]# sed -i '/UseDNS/cUseDNS no' /etc/ssh/sshd_config
[root@gjy ~]# sed -i '/GSSAPIAuthentication/c#GSSAPIAuthentication no' /etc/ssh/sshd_config

删除命令d

#指定删除第三行, 但不会改变文件内容
[root@gjy ~]# sed '3d' passwd
[root@gjy ~]# sed '3{d}' passwd
#从第三行删除到最后一行
[root@gjy ~]# sed '3,$d' passwd
#删除最后一行
[root@gjy ~]# sed '$d' passwd
#删除所有的行
[root@gjy ~]# sed '1,$d' passwd
#匹配字符串进行该行删除
[root@gjy ~]# sed '/mail/d' passwd

插入命令i

#在文件的某一行上面添加内容
[root@gjy ~]# sed -i '30i listen 80;' passwd

写文件命令w

#将匹配到的行写入到新文件中
[root@gjy ~]# sed -n '/root/w newfile' passwd
#将passwd文件的第二行写入到newfile中
[root@gjy ~]# sed -n '2w newfile' passwd

获取下一行命令n

#匹配root的行, 删除root行的下一列
[root@gjy ~]# sed '/root/{n;d}' passwd
#替换匹配root行的下一列
[root@gjy ~]# sed '/root/{n; s/bin/test/}' passwd

暂存和取用命令h H g G

#将第一行的写入到暂存区, 替换最后一行的内容
[root@gjy ~]# sed '1h;$g' /etc/hosts
#将第一行的写入到暂存区, 在最后一行调用暂存区的内容
[root@gjy ~]# sed '1h;$G' /etc/hosts
#将第一行的内容删除但保留至暂存区, 在最后一行调用暂存区内容追加至于尾部
[root@gjy ~]# sed '1{h;d};$G' /etc/hosts
#将第一行的内容写入至暂存区, 从第二行开始进行重定向替换
[root@gjy ~]# sed '1h;2,$g' /etc/hosts
#将第一行重定向至暂存区, 2-3行追加至暂存区, 最后追加调用暂存区的内容
[root@gjy ~]# sed '1h; 2,3H; $G' /etc/hosts
[root@gjy ~]# sed '1,3H; $G' /etc/hosts

反向选择命令!

#除了第三行,其他全部删除
[root@gjy ~]# sed '3!d' /etc/hosts

03. Sed匹配替换

s #替换命令标志

g #行内全局替换

i #忽略替换大小写

替换命令s

#替换每行出现的第一个root
[root@gjy ~]# sed 's/root/alice/' passwd
#替换以root开头的行
[root@gjy ~]# sed 's/^root/alice/' passwd
#查找匹配到的行, 在匹配的行后面添加内容
[root@gjy ~]# sed 's/[0-9][0-9]$/& new/' passwd
#匹配包含有root的行进行替换
[root@gjy ~]# sed 's/root/alice/g' passwd
#匹配包含有root的行进行替换,忽略大小写
[root@gjy ~]# sed 's/root/alice/gi' /etc/passwd
#后向引用
[root@gjy ~]# sed -r 's#(roo)#\1-alice#g' passwd
[root@gjy ~]# ifconfig eth0|sed -n '2p'|sed -r 's#(^.*et) (.*) (net.*$)#\2#g'
#示例
[root@web ~]# vim a.txt
/etc/abc/456
etc
#删除文本中的内容,需加转义
[root@gjy ~]# sed '/\/etc\/abc\/456/d' a.txt
#如果碰到/符号, 建议使用#符替换
[root@gjy ~]# sed 's#/etc/abc/456#/dev/null#g' a.txt
[root@gjy ~]# sed 's@/etc/abc/456@/dev/null@' a.txt

删除文件

#删除配置文件中#号开头的注释行, 如果碰到tab或空格是无法删除
[root@gjy ~]# sed '/^#/d' file
#删除配置文件中含有tab键的注释行
[root@gjy ~]# sed -r '/^[ \t]*#/d' file
#删除无内容空行
[root@gjy ~]# sed -r '/^[ \t]*$/d' file
#删除注释行及空行
[root@gjy ~]# sed -r '/^[ \t]*#/d; /^[ \t]*$/d' /etc/vsftpd/vsftpd.conf
[root@gjy ~]# sed -r '/^[ \t]*#|^[ \t]*$/d' /etc/vsftpd/vsftpd.conf
[root@gjy ~]# sed -r '/^[ \t]*($|#)/d' /etc/vsftpd/vsftpd.conf

给文件行添加注释

#将第二行到第六行加上注释信息
[root@gjy ~]# sed '2,6s/^/#/' passwd
#将第二行到第六行最前面添加#注释符
[root@gjy ~]# sed -r '2,6s/.*/#&/' passwd
#添加#注释符
[root@gjy ~]# sed -r '3,$ s/^#*/#/' passwd
[root@gjy ~]# sed -r '3,$ s/^/#/' passwd
[root@gjy ~]# sed -r '30,50s/^[ \t]*#*/#/' /etc/nginx.conf
[root@gjy ~]# sed -r '2,8s/^[ \t#]*/#/' /etc/nginx.conf

5. 正则表达式之AWK文本处理

01. Awk基本介绍

什么是Awk?

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。

awk数据可以来自标准输入、一个或多个文件,或其它命令的输出。

awk通常是配合脚本进行使用, 是一个强大的文本处理工具。

awk 的处理文本和数据的方式如下:

1.进行逐行扫描文件, 从第一行到最后一行

2.寻找匹配的特定模式的行,在行上进行操作

3.如果没有指定处理动作,则把匹配的行显示到标准输出

4.如果没有指定模式,则所有被操作的行都被处理

Awk语法格式。

awk 的语法格式awk [options] 'commands' filenames

#命令 command行处理前     行处理     行处理后
BEGIN{} {} END{}
#BEGIN发生在读文件之前
[root@gjy ~]# awk 'BEGIN{print 1/2}'
0.5
#BEGIN在行处理前, 修改字段分隔符
[root@gjy ~]# awk 'BEGIN{FS=":"} {print $1}' /etc/passwd
#BEGIN在行处理前, 修改字段读入和输出分隔符
[root@gjy ~]# awk 'BEGIN{FS=":";OFS="---"} {print $1,$2}' /etc/passwd
#示例
[root@gjy ~]# awk 'BEGIN{print 1/2} {print "ok"} END {print "Game Over"}' /etc/hosts
0.5
ok
ok
ok
Game Over

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中,覆盖原来的内容,然后将新的字符串分隔成字段并进行处理。该过程将持续到所有行处理完毕.

Awk命令格式

#示例1, 匹配 awk 'pattern' filename
[root@gjy ~]# awk '/root/' /etc/passwd
#示例2, 处理动作 awk '{action}' filename
[root@gjy ~]# awk -F: '{print $1}' /etc/passwd
#示例3, 匹配+处理动作 awk 'pattern {action}' filename
[root@gjy ~]# awk -F ':' '/root/ {print $1,$3}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"} /root/{print $1,$3}' /etc/passwd
#示例4, 判断大于多少则输出什么内容 command |awk 'pattern {action}'
[root@gjy ~]# df |awk '/\/$/ {if ($3>50000) print $4}'

02. Awk分隔符

e在学习awk的过程中,我们先来快速的熟悉下awk分隔符的作用。
请事先准备如下数据文件:
[root@gjy ~]# cat awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65

Awk指定多个分隔符,Awk默认以空白行作为分隔符

#1.如何查看文件中的第一列
[root@gjy ~]# awk '{print $1}' awk_file.txt
ll
kk
hh
jj
mm
#2.如果有的文件不是以空格为分隔符怎么办?比如/etc/passwdh
[root@gjy ~]# awk -F: '{print $7}' passwd |tail -1
/bin/bash
#3.如何指定多个分隔符,比如想获取第二列的内容?
[root@gjy ~]# cat awk_file.txt
ll:1990 50 51 61
kk:1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
#以冒号或空格为分隔符
[root@gjy ~]# awk -F '[: ]' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994
#4.指定多个分隔符
[root@gjy ~]# cat awk_file.txt
ll::1990 50 51 61
kk:1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
#[: ]+连续的多个冒号当一个分隔符,连续的多个空格当一个分隔符,连续空格和冒号也当做一个字符来处理
[root@gjy ~]# awk -F '[: ]+' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994

03. Awk内部变量

要想了解awk的一些内部变量需要先准备如下数据文件。
[root@gjy ~]# cat awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65

3.1 Awk内置变量NF,保存每行的最后一列

#1.通过print打印,NF和$NF,你发现了什么?
[root@gjy ~]# awk '{print NF,$NF}' awk_file.txt
5 61
5 62
5 63
5 64
5 65
#如果将第五行的55置为空,那么该如何在获取最后一列的数字?
[root@gjy ~]# awk '{print $5}' awk_file.txt
61
62
63
64
#最后一列为空,为什么?
#使用$NF为什么就能成功?(因为NF变量保存的是每一行的最后一列)
[root@gjy ~]# awk '{print $NF}' awk_file.txt
61
62
63
64
65
#2.如果一个文件很长,靠数列数需要很长的时间,那如何快速打印倒数第二列?
[root@gjy ~]# awk '{print $(NF-1)}' awk_file.txt
51
52
53
54
90

3.2 Awk内置变量$0,完整的当前文件的内容

[root@gjy ~]# awk '{print $0}' awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 65

3.3 Awk内置变量NR,表示记录行号

#1.使用print打印NR,会发现NR会记录每行文件的行号
[root@gjy ~]# awk '{print NR,$0}' awk_file.txt
1 ll 1990 50 51 61
2 kk 1991 60 52 62
3 hh 1992 70 53 63
4 jj 1993 80 54 64
5 mm 1994 90 65
#2.那如果我们想打印第二行到第三行的内容怎么办?
[root@gjy ~]# awk 'NR>1&&NR<4 {print NR,$0}' awk_file.txt
2 kk 1991 60 52 62
3 hh 1992 70 53 63
#2.那如果只想打印第三行,该怎么办?
[root@gjy ~]# awk 'NR==3 {print NR,$0}' awk_file.txt
3 hh 1992 70 53 63
#3.那如果既想打印第三行,又想打印第一列?
[root@gjy ~]# awk 'NR==3 {print NR,$1}' awk_file.txt
3 hh

3.4 Awk内置变量FNR,记录输入每个文件的编号

[root@gjy ~]# awk '{print FNR,$0}' /etc/passwd /etc/hosts

3.5 Awk内置变量,FS指定字段分割符, 默认是空格

#以冒号作为字段分隔符
[root@gjy ~]# awk -F: '/root/{print $1,$3}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"} {print $1,$3}' /etc/passwd
[root@gjy ~]# awk -v FS=: '{print $1,$3}' /etc/passwd
#以空格冒号tab作为字段分割
[root@Shell ~]# awk -F '[ :\t]' '{print $1,$2,$3}' /etc/passwd

3.6 Awk内置变量OFS,指定输出字段分隔符

#,逗号映射为OFS, 初始情况下OFS变量是空格
[root@gjy ~]# awk -F: '/root/{print $1,$2,$3,$4}' /etc/passwd
[root@gjy ~]# awk 'BEGIN{FS=":"; OFS="+++"} /^root/{print $1,$2}' /etc/passwd
[root@gjy ~]# awk -v FS=":" -v OFS="+++" '/^root/{print $1,$2}' /etc/passwd

3.7 Awk内置变量RS,输入记录分隔符,默认为换行符(了解)

[root@gjy ~]# cat test.txt
oldboy/oldgirl/olddog
[root@gjy ~]# awk 'BEGIN{RS="/"}{print $0}' test.txt
oldboy
oldgirl
olddog

3.8 Awk内置变量ORS,将文件每一行合并为一行,以空格为分割(了解)

[root@gjy ~]# awk 'BEGIN{ORS="#"} {print $0}' /etc/hosts

3.9 Print格式化输出函数

[root@gjy ~]# date|awk '{print "本月是:"$2 "\n今年是:"$NF}'
[root@gjy ~]# awk -F: '{print "用户是:" $1 "\t 用户uid: " $3 "\t 用户gid:" $4}' /etc/passwd
#printf函数(了解)
[root@gjy ~]# awk -F: '{printf "%-15s %-10s %-15s\n", $1, $2, $3}' /etc/passwd
#%s字符类型,%d数值类型,占15字符, -表示左对齐,默认是右对齐,printf默认不会在行尾自动换行,加\n

04. Awk模式动作

awk语句都由模式和动作组成。
模式部分决定动作语句何时触发及触发事件。
如果省略模式部分,动作将时刻保持执行状态。模式可以是条件语句或复合语句或正则表达式。

4.1 正则表达式

#匹配记录(整行)
[root@gjy ~]# awk '/^root/' /etc/passwd
[root@gjy ~]# awk '$0 ~/^root/' /etc/passwd
#匹配字段:匹配操作符(~ !~)
[root@gjy ~]# awk '!/^root/' /etc/passwd
[root@gjy ~]# awk '$0 !~ /^root/' /etc/passwd

4.2 比较表达式

比较表达式采用对文本进行比较,只有当条件为真,才执行指定的动作。比较表达式使用关系运算符,用于比较数字与字符串。

关系运算符

运算符含义示例
< 小于 x<y
<= 小于等于 x<=y
== 等于 x==y
!= 不等于 x!=y
>= 大于等于 x>=y
> 大于 x>y
#uid为0的列出来
[root@gjy ~]# awk -F ":" '$3==0' /etc/passwd
#uid小于10的全部列出来
[root@gjy ~]# awk -F: '$3 < 10' /etc/passwd
#用户登陆的shell等于/bin/bash
[root@gjy ~]# awk -F: '$7 == "/bin/bash" ' /etc/passwd
#第一列为alice的列出来
[root@gjy ~]# awk -F: '$1 == "alice" ' /etc/passwd
#为alice的用户列出来
[root@gjy ~]# awk -F: '$1 ~ /alice/ ' /etc/passwd
[root@gjy ~]# awk -F: '$1 !~ /alice/ ' /etc/passwd
#磁盘使用率大于多少则,则打印可用的值
[root@gjy ~]# df |awk '/\/$/'|awk '$3>1000000 {print $4}'

4.3 条件表达式

[root@gjy ~]# awk -F: '$3>300 {print $0}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3>300) print $0}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3>5555){print $3} else {print $1}}' /etc/passwd

4.4 运算表达式

[root@gjy ~]# awk -F: '$3 * 10 > 500000' /etc/passwd
[root@gjy ~]# awk -F: 'BEGIN{OFS="--"} { if($3*10>50000) {print $1,$3} } END {print "打印ok"}' /etc/passwd
[root@gjy ~]# awk -F: '/sshd/{print $3}' passwd
74
[root@gjy ~]# awk -F: '/sshd/{print $3 + 10 }' passwd
84
[root@gjy ~]# awk -F: '/sshd/{print $3 + 10.56 }' passwd
84.56
[root@gjy ~]# awk -F: '/sshd/{print $3 - 10 }' passwd
64
[root@gjy ~]# awk -F: '/sshd/{print $3 * 10 }' passwd
740
[root@gjy ~]# awk -F: '/sshd/{print $3 / 10 }' passwd
7.4
[root@gjy ~]# awk -F: '/sshd/{print $3 % 10 }' passwd
4[root@gjy ~]# awk 'BEGIN{print 85 + 10 }'
95
[root@gjy ~]# awk 'BEGIN{print 85 - 10 }'
75
[root@gjy ~]# awk 'BEGIN{print 85 * 10 }'
850
[root@gjy ~]# awk 'BEGIN{print 85 / 10 }'
8.5
[root@gjy ~]# awk 'BEGIN{print 85 % 10 }'
5
[root@gjy ~]# awk 'BEGIN{print 85 ^ 10 }'
19687440434072264704

4.5 逻辑操作符和复合模式

&& 逻辑与

|| 逻辑或

! 逻辑非

#匹配用户名为root并且打印uid小于15的行
[root@gjy ~]# awk -F: '$1~/root/ && $3<=15' /etc/passwd
#匹配用户名为root或uid大于5000
[root@gjy ~]# awk -F: '$1~/root/ || $3>=5000' /etc/passwd
#匹配不是以root开头的行
[root@gjy ~]# awk '!/^root/' /etc/passwd

Awk示例1:解释其下列命令的含义

# awk '/west/' datafile
# awk '/^north/' datafile
# awk '$3 ~ /^north/' datafile
# awk '/^(no|so)/' datafile
# 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
# awk '/^[ns]/{print $1}' datafile
# awk '$5 ~ /\. [7-9]+/' datafile
# awk '$2 !~ /E/{print $1,$2}' datafile
# awk '$3 ~ /^Joel/{print $3 "is a nice boy."}' datafile
# awk '$8 ~ /[0-9][0-9]$/{print $8}' datafile
# awk '$4 ~ /Chin$/{print "The price is $" $8 "."}' datafile
# awk '/Tj/{print $0}' datafile
# awk -F: '{print "Number of fields: "NF}' /etc/passwd
# awk -F"[ :]" '{print NF}' /etc/passwd

Awk示例2

[root@gjy ~]# cat b.txt
web qiudao:is a:good boy!
[root@gjy ~]# awk '{print NF}' b.txt
4
[root@gjy ~]# awk -F ':' '{print NF}' b.txt
3
[root@gjy ~]# awk -F"[ :]" '{print NF}' b.txt
6

05. Awk条件判断

if语句格式:{ if(表达式){语句;语句;... }}
#打印当前管理员用户名称
[root@gjy ~]# awk -F: '{ if($3==0){print $1 "is adminisitrator"} }' /etc/passwd
#统计系统用户数量
65
[root@gjy ~]# awk -F: '{ if($3>0 && $3<1000){i++}} END {print i}' /etc/passwd
#统计普通用户数量
[root@gjy ~]# awk -F: '{ if($3>1000){i++}} END {print i}' /etc/passwd
if...else语句格式:{if(表达式){语句;语句;... }else{语句;语句;...}}[root@gjy ~]# awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd
[root@gjy ~]# awk -F: '{if($3==0){count++} else{i++}} END{print " 管理员个数: "count ; print " 系统用户数: "i}' /etc/passwd if...else if...else语句格式:{if(表达式 1){语句;语句;... }else if(表达式 2){语句;语句;. .. }else{语句;语句;... }}
[root@gjy ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print i;print j;print k}' /etc/passwd
[root@gjy ~]# awk -F: '{ if($3==0){i++} else if($3>0 && $3<1000){j++} else if($3>1000) {k++}} END {print "管理员个数"i; print "系统用户个数" j; print "系统用户个数" k }' /etc/passwd

06. Awk循环语句

while循环
[root@gjy ~]# awk 'BEGIN{ i=1; while(i<=10){print i; i++} }'
[root@gjy ~]# awk -F: '{i=1; while(i<=NF){print i; i++}}' /etc/passwd
[root@gjy ~]# awk -F: '{i=1; while(i<=10) {print $0; i++}}' /etc/passwd
[root@gjy ~]# cat b.txt
111 222
333 444 555
666 777 888 999
[root@gjy ~]# awk '{i=1; while(i<=NF){print $i; i++}}' b.txt
for循环#C 风格 for
[root@gjy ~]# awk 'BEGIN{for(i=1;i<=5;i++){print i} }'
#将每行打印 10 次
[root@gjy ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' passwd

07. Awk数组概述

将需要统计的某个字段作为数组的索引,然后对索引进行遍历

7.1 统计/etc/passwd 中各种类型 shell 的数量

[root@gjy ~]# awk -F: '{shells[$NF]++} END{ for(i in shells){print i,shells[i]} }' /etc/passwd

7.2 网站访问状态统计<当前时实状态ss>

[root@gjy ~]# ss -an|awk '/:80/{tcp[$2]++} END {for(i in tcp){print i,tcp[i]}}'

7.3 统计当前的tcp的11种状态数量<当前时实状态 netstat,ss>

[root@gjy ~]# ss -ant|sed '1d'|awk '{status[$1]++} END {for(i in status){print i,status[i]}}'

08. Awk数组案例

Nginx日志分析,日志格式如下:

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';52.55.21.59 - - [22/Nova/2018:14:55:36 +0800] "GET /feed/ HTTP/1.1" 404 162 "https:#www.google.com/" "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; de) Presto/2.9.168 Version/11.52" "-"

8.1 统计2018年11月22日,当天的PV量

[root@gjy ~]# grep "22/Nov/2018" access.log |wc -l
[root@gjy ~]# awk "/22\/Nov\/2018/" access.log |wc -l
[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips) {sum+=ips[i]} {print sum}}' access.log
#统计11-12点的pv量
[root@gjy ~]# awk '$4>="[22/Nov/2018:11:00:00" && $4<="[22/Nov/2018:12:00:00 {print $0}"' access.log |wc -l

8.2 统计2018年11月22日,一天内访问最多的10个IP

[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){ print ips[i],i}}' access.log |sort -rn|head
#统计11-12点访问次数最多的10个IP
[root@gjy ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00"' access.log |awk '{ips[$1]++} END {for(i in ips){print ips[i],i}}'|sort -rn|head

8.3 统计2018年11月22日,访问大于100次的IP

[root@gjy ~]# awk '/22\/Nov\/2018/ {ips[$1]++} END {for(i in ips){if(ips[i]>100){print i,ips[i]}}}' access.log

8.4 统计2018年11月22日,访问最多的10个页面($request top 10)

[root@gjy ~]# awk '/22\/Nov\/2018/ {request[$7]++} END {for(i in request){print request[i],i}}' access.log |sort -rn|head

8.5 统计2018年11月22日,每个URL访问内容总大小($bodybytessent)

[root@gjy ~]# awk '/22\/Nov\/2018/{size[$7]+=$10} END {for(i in size){print size[i],i}}' access.log |sort -rn|head

8.6 统计2018年11月22日,每个IP访问状态码数量($status)

[root@gjy ~]# awk '{ip_code[$1 " " $9]++} END {for(i in ip_code){print ip_code[i],i}}' access.log|sort -rn|head

8.7 统计2018年11月22日,访问状态码为404及出现的次数($status)

[root@gjy ~]# grep "404" access.log |wc -l
[root@gjy ~]# awk '{if($9=="404") code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.8 统计2018年11月22日,8:30-9:00访问状态码是404

[root@gjy ~]# awk '$4>="[22/Nov/2018:15:00:00" && $4<="[22/Nov/2018:19:00:00" && $9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log
[root@gjy ~]# awk '$9=="404" {code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.9 统计2018年11月22日,各种状态码数量

[root@gjy ~]# awk '{code[$9]++} END {for(i in code){print i,code[i]}}' access.log

8.10 统计日志中所有URL访问的次数及访问响应的内容总大小

[root@gjy ~]# awk '{request[$7]++;size[$7]+=$10} END {for(i in request){print request[i],i,size[i]}}' access.log |sort -rn|head

Shell07--正则应用的更多相关文章

  1. Javascript正则对象方法与字符串正则方法总结

    正则对象 var reg = new Regexp('abc','gi') var reg = /abc/ig 正则方法 test方法(测试某个字符串是否匹配) var str = 'abc123'; ...

  2. C#-正则,常用几种数据解析-端午快乐

    在等待几个小时就是端午节了,这里预祝各位节日快乐. 这里分享的是几个在C#中常用的正则解析数据写法,其实就是Regex类,至于正则的匹配格式,请仔细阅读正则的api文档,此处不具体说明,谢谢. 开始吧 ...

  3. Javascript 中 with 的替代方案和String 中的正则方法

    这几天在升级自己的MVVM 框架,遇到很多小问题,就在这里统一解决了. with 语法 在代码中,要执行这么一个函数 function computeExpression(exp, scope) { ...

  4. JavaScript与PHP中正则

    一.JavaScript 有个在线调试正则的工具,点击查看工具.下面的所有示例代码,都可以在codepen上查看到. 1.创建正则表达式 var re = /ab+c/; //方式一 正则表达式字面量 ...

  5. Java正则速成秘籍(一)之招式篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  6. Java正则速成秘籍(二)之心法篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  7. Java正则速成秘籍(三)之见招拆招篇

    导读 正则表达式是什么?有什么用? 正则表达式(Regular Expression)是一种文本规则,可以用来校验.查找.替换与规则匹配的文本. 又爱又恨的正则 正则表达式是一个强大的文本匹配工具,但 ...

  8. python浅谈正则的常用方法

    python浅谈正则的常用方法覆盖范围70%以上 上一次很多朋友写文字屏蔽说到要用正则表达,其实不是我不想用(我正则用得不是很多,看过我之前爬虫的都知道,我直接用BeautifulSoup的网页标签去 ...

  9. [Python基础知识]正则

    import re str4 = r"^http://qy.chinahr.com/cvm/preview\?cvid=\w{24,25}&from=sou&gtid=\w{ ...

  10. iOS中使用正则

    一.什么是正则表达式 正则表达式,又称正规表示法,是对字符串操作的一种逻辑公式.正则表达式可以检测给定的字符串是否符合我们定义的逻辑,也可以从字符串中获取我们想要的特定部分.它可以迅速地用极简单的方式 ...

随机推荐

  1. pspice建立仿真模型元件库

    摘自:http://royroyyy.blog.163.com/blog/static/1376506172011026102216175/ PSpice9.2电子元器件模型--由网页下载的model ...

  2. 使用vue进行国际化

    相对于网站等一些需求 我们有需要做国际化的需求,具体步骤如下: 首先安装 vue-i18n npm install vue-i18n import VueI18n from 'vue-i18n' Vu ...

  3. MJ瀑布流学习笔记

    1. 如果系统自带的布局的话,是这样: //系统自带的UICollectionViewFlowLayout 而不是UICollectionViewLayout UICollectionViewFlow ...

  4. 20180711-Java Number类

    下面是一个装箱与拆箱的例子: public class Test{ public static void main(String args[]){ Integer x = 5; // boxes in ...

  5. 从React渲染流程分析Diff算法

    1.什么是虚拟DOM 在React中,render执行的结果得到的并不是真正的DOM节点,结果仅仅是轻量级的JavaScript对象,我们称之为virtual DOM. 简单的说,其实所谓的virtu ...

  6. toutiao url

    https://it.snssdk.com/article/v2/tab_comments/?group_id=6485899113563947533&item_id=648589911356 ...

  7. JAVA中short和short相加自动转化为int

    精度小于int的数值运算的时候都回被自动转换为int后进行计算 所以,下面的代码会报编译错误 short s1 = 1;short s2 = 1;s1= (s1+s2); 必须改成: short s1 ...

  8. Log4j log for java(java的日志) 的使用

    log4j的使用,Log4j log for java(java的日志) 是java主流的日志框架,提供各种类型,各种存储,各种格式,多样化的日志服务. 可以再Apache官网下载得到. 我们下载lo ...

  9. Oracle系列:触发器、作业、序列、连接

    .Net程序员学用Oracle系列(8):触发器.作业.序列.连接   1.触发器 2.作业 2.1.作业调度功能和应用 2.2.通过 DBMS_JOB 来调度作业 3.序列 3.1.创建序列 3.2 ...

  10. C++ STL:优先队列的使用详解

    堆是一个很重要的数据结构,那么我们如何更加简洁的去写大根/小根堆呢? 对于很多语言来说,只能一步一步手打,但是对于C++来说,写大根小根堆就简便得多,因为C++中有一个容器叫做priority_que ...