目录
1.6 grep通用正则表达式分析程序(golobal search regular expression and printing)
一、正则表达式(regular expression)
定义:使用一些特殊符号、字母和数字,按照某个规则组合成一个公式用来表示某个含义,即为正则表达式,它是一种方法。
许多命令都可以采用正则表达式,例如:vim、grep、sed、awk等 ———— 在查找的时候,使用正则表达式会更加便捷。
写正则表达式 -- 找规律和共性问题
分为: 1.基本正则(元字符) :* . ^ $
2.扩展正则(元字符):在基本正则的基础上增加了 | + ? {}
【区别】扩展正则支持更多的元字符,可以表示更复杂的含义,功能更加完善。
1.1 元字符
定义:有特殊含义的字符
^ 表示以什么开头
$ 表示以什么结尾
? 表示前一个字符出现0或者1次
+ 表示前一个字符出现1次以上
* 表示前一个字符出现0次或者任意次
| 表示或者
\s 表示空格
\< 表示单词以什么开头
\> 表示单词以什么结尾
\b 在字符串前,表示以什么开头;在字符串后,表示以什么结尾
1.2 正则表达式的元素组成
{n} 表示前一个字符出现n次
{a,b} 表示前一个字符出现a到b次
【举例】
1.3 通配符
[abc] 取中括号里的任意一个字符a或b或c
egrep [^a-Z] 取反,表示查找不含字母的内容
egrep -v "[a-Z]" 取反,表示查找不含字母的行
1.4 分组和转义字符
1.5 实例
1. 找出文件里包含.jpg或.png的行
[root@192 ~]# cat sc.html |egrep ".jpg|.png"
<img src=wgyc.png width="400" >
<img src=luogan.png width="400" >
<img src=xiayuzhen.jpg width="400" >
2. 找出以<h1开头的行
[root@192 ~]# cat sc.html | egrep "^<h1"
<h1>Welcome to sanchuang!</h1>
<h1>三创同乐欢迎您!</h1>
3. 对元字符*含义中“前一个字符”的理解
[root@192 ~]# echo lihua | egrep "lig*"
lihua
[root@192 ~]# echo $?
0
[root@192 ~]# echo lihua | egrep "lig+"
[root@192 ~]# echo $?
1
4. 找出字符串中符合条件的内容(\s,.*,{}的用法)
5. 找出字符串中符合条件的内容({}和+的用法)
6. 找出文件的有效行(不包含注释行和空行)
[root@192 0701]# cat /etc/ssh/sshd_config |egrep -v "^#|^$"
7. 查找文件中不以数字开头的行
[root@192 0701]# cat name.txt |egrep "^[^0-9]"
8. 查找文本里单词的长度是13个字符的单词
egrep "\b[a-Z]{13}\b"
1.6 grep通用正则表达式分析程序(golobal search regular expression and printing)
用途:使用正则表达式搜所文本,并将匹配的行打印处来
格式:grep [选项]... 模式 目标文件
1.6.1 选项
-i 不区分大小写(--ignore-case)
-n 输出行号(--line-number)
-o 只显示匹配内容(--only-matching)
-v 反转查找,输出与模式不相符的行
-A 在什么之后(after)
-B 在身之前(before)
-C 上下文(context)
-E 扩展正则(--exitend-regexp)= egrep
-r 递归查找
[root@192 0701]# cat name.txt
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
wenke wenkeke
wanglianfang fangfang
liyili lili
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
wenke wenkeke
wanglianfang fangfang
liyili lili
[root@192 0701]# cat name.txt |grep -B2 "lizhuofu" # 找到含有lizhuofu的行的前两行
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
--
liyili lili
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
[root@192 0701]# cat name.txt |grep -A2 "lizhuofu" # 找到含有lizhuofu的行的后两行
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
--
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
[root@192 0701]# cat name.txt |grep -C2 "lizhuofu" # 找到含有lizhuofu的行的前后两行
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
--
liyili lili
zhengyang ZHENGYANG
LIZHUOFU lizhuofu123 12345 lizhuofu
xiaomi huawei opp0
XIAOMI xiaomi12234+56 sc@163.com
1.6.2 实例
【举例】递归找到/lianxi下所有包含“xiaomi”的文件
1.7 练习
1.7.1 简单练习
1、进入/lianxi目录,复制/etc/passwd到当前目录下,然后对passwd进行操作
[root@192 ~]# cd /lianxi [root@192 lianxi]# cp /etc/passwd .
2、查找出当前passwd文件中以ftp或者mail开头的行,在屏幕上输出。
[root@192 lianxi]# cat passwd |egrep "^ftp|^mail"
3、查找出当前passwd文件中首行不是以r、m、f开头的行,在屏幕上输出。
[root@192 lianxi]# cat passwd |egrep -v "^[rmf]"
4、查找出当前passwd文件中以bash结尾的行。
[root@192 lianxi]# cat passwd |egrep "bash$"
5、查找出/etc/login.defs文件中的有效行(不显示空行和注释行)。
[root@192 lianxi]# cat /etc/login.defs |egrep -v "^#|^$"
6、查找出/var/log/messages文档中有16个字母的单词
[root@192 lianxi]# cat /var/log/messages |egrep "\b[a-Z]{16}\b"
7、查找出来/etc/passwd文件里用户名包含liu同时使用bash的用户
[root@192 lianxi]# cat /etc/passwd |egrep "[0-Z]*liu[0-Z]*" |egrep "bash$"
8、查找/etc/ssh/sshd_config 里的有效行
[root@192 lianxi]# cat /etc/ssh/sshd_config |egrep -v "^#|^$"
9、查找出/etc/ssh/sshd_config 文件里的包含连续2个数字的行
[root@192 lianxi]# cat /etc/ssh/sshd_config |egrep "\b[0-9]{2}\b"
10、查找出/etc/ssh/sshd_config包含特殊字符的行
[root@192 lianxi]# cat /etc/ssh/sshd_config |egrep "[^0-Z]"
11、查找出/etc/ssh/sshd_config不包含数字的行
[root@192 lianxi]# cat /etc/ssh/sshd_config |egrep -v "[0-9]"
12、写一个表示下面网址的正则表达式出来。例如:
百度一下,你就知道 fjdkfjdkfj
home.sina.com fengdeyong
中国铁路12306 1212121
http://www.qillu.edu sanchuang
rsync://www.github.com/abc
ftp://www.baidu.com 12112
[root@192 0701]# cat website.txt |egrep -o "[a-Z]+://([0-Z]+\.){2}[0-Z]+"
13、时间的正则
时间的正则,表示18/Dec/2021:16:54分钟到18/Dec/2021:16:58分钟
[root@192 0701]# cat access.log |egrep "18/Dec/2021:16:5[4-8]"
1.7.2 从文本中过滤出所有邮箱地址
[root@192 0701]# cat mail.txt
wang sheng hu 8898989@qq.com fjdkfjd
fengdeyong@sina.com fjdkfjd
zhao zhao@163.com
yishiying_1213@163.com fjdkfjdkjfk
15、写一个表示邮箱的正则
feng@qq.com changsha
1234feng@163.com fengdeyong
meng.xianhui@yahoo.cn sanchuang
liudehua@sina.com
10001@qq.com
123_ui@12306.cn
qilu@qilu.edu
qilu@qilu.edu/fjdkfjk/fjdk
分析:找出邮箱地址的共同点
格式 --- 字符串1@字符串2.字符串3
字符串1:a-Z _ 0-9
字符串2:a-Z 0-9
字符串3:a-Z
[root@192 0701]# cat mail.txt |egrep -o "[0-Z_]+@[0-z]+\.[a-z]+" |sort |uniq # sort:排序,uniq:去重
10001@qq.com
1234feng@163.com
123_ui@12306.cn
8898989@qq.com
fengdeyong@sina.com
feng@qq.com
liudehua@sina.com
qilu@qilu.edu
xianhui@yahoo.cn
yishiying_1213@163.com
zhao@163.com
1.7.3 👍日志分析
算出2022年7月份里的每一个分钟的流量,具体日志文件格式如下:
2022-7-1 00:01:01 78
2022-7-1 00:01:04 89
2022-7-1 00:03:01 178
2022-7-1 00:03:05 890
2022-7-2 00:03:01 178
2022-7-3 00:03:05 890
....
2022-7-30 00:03:01 178
2022-7-31 00:07:05 8900
[root@192 0704]# cat access.log
2022-7-1 00:01:01 78
2022-7-1 00:01:04 89
2022-7-1 00:03:01 178
2022-7-1 00:03:05 890
2022-7-2 00:03:01 178
2022-7-3 00:03:05 890
2022-7-5 10:03:05 890
2022-7-5 19:03:05 5213
2022-7-6 20:03:05 800
2022-7-10 12:08:45 900
2022-7-11 16:33:25 5130
2022-7-30 00:03:01 178
2022-7-31 00:07:05 8900
脚本
#!/bin/bash
for i in {1..31}
do
for j in {00..23}
do
for k in {00..59}
do
echo -e "2022-7-$i $j:$k \c" >> result.txt
egrep "2022-7-$i\s$j:$k:[0-5][0-9]" /lianxi/0704/access.log |awk '{sum+=$3} END{print sum}' >> result.txt
echo ''
done
done
done
一条命令搞定
[root@192 0704]# awk '{time[$1,substr($1,5,1),substr($2,1,5)]+=$3}END{for (i in time)print i,time[i]}' access.log |sort -n -k 3 -t -
2022-7-1-00:01 167
2022-7-1-00:03 1068
2022-7-2-00:03 178
2022-7-3-00:03 890
2022-7-5-10:03 890
2022-7-5-19:03 5213
2022-7-6-20:03 800
2022-7-10-12:08 900
2022-7-11-16:33 5130
2022-7-30-00:03 178
2022-7-31-00:07 8900
substr($1,5,1) 表示截取第一个字段中第5个字符及之后的1个字符,包括第5个字符
sort -n -k 3 -t - 以-作为分割符,将第三个字段按数值排序
1.7.4 👍IP地址的正则
A类: head -1000 access.log |egrep "\b([1-9]|[1-9][0-9]|1[01][0-9]|12[0-6])(\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}\b"
二、sort排序
默认情况下,根据一行中第一个字符的ASCII码值进行比较,升序排列,当第一个字符一样时,就根据第二个字符进行比较
-n 将其按照数值比较(--numeric-sort)
-k 指定列排序(--key=KEYDEF)
-r 降序排列(--reverse)
-t 指定分割符(--file-separator=SEP)
sort默认以空白(空格和Tab键)作为分割,多个连续空格为一个空白
[root@192 0701]# cat grade.txt
id name chinese english math
1 cali 80 80 80
2 tom 90 90 70
3 jarry 70 100 90
[root@192 0701]# cat grade.txt |sort -k 4 -n -r|head -3
3 jarry 70 100 90
2 tom 90 90 70
1 cali 80 80 80
三、uniq去重
去除重复行,默认情况下只能去除连续的重复行,所以uniq一般和sort同时使用
-c 统计重复的次数(count)
[root@192 0701]# cat test.txt |uniq
lihua
fanyouyou
lihua
wangxiaoli
[root@192 0701]# cat test.txt |sort| uniq
fanyouyou
lihua
wangxiaoli
[root@192 0701]# cat test.txt |sort| uniq -c
13 fanyouyou
13 lihua
15 wangxiaoli
[root@192 0701]# cat test.txt |sort| uniq -c|sort -nr
15 wangxiaoli
13 lihua
13 fanyouyou