目录
一.正则表达式
1.主要用来匹配字符串(命令结果,文本内容),
通配符匹配文件(而且是已存在的文件)
基本正则表达式
扩展正则表达式
. 表示任意一个字符
[]取其中一个
[^]排除
[root@localhost ~]# echo abc |grep a.c //表示原来的点需要加\转义
abc
[root@localhost ~]# echo abc |grep 'a\.c' ==//标准格式需要加'' 或者""==
[root@localhost ~]# ls |grep '[zhou].txt' // 匹配[]中任意一个字符
h.txt
o.txt
u.txt
z.txt
[root@localhost ~]# ls |grep '[^a-z].txt' //显示非小写字母
A.txt
B.txt
2.表示次数
#匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.*#任意长度的任意字符
?#匹配其前面的字符出现0次或1次,即:可有可无
+#匹配其前面的字符出现最少1次,即:肯定有且 >=l次
{n}#匹配前面的字符n次
{m,n}#匹配前面的字符至少m次,至多n次
{,n}#匹配前面的字符至多n次,<=n
/{n,} #匹配前面的字符至少n次
[root@localhost ~]# echo google |grep 'go\{2\}gle' \\带表前面的o出现2次
google
[root@localhost ~]# echo gooooogle |grep 'go\{2,\}gle' \\带表前面的o出现2次以上
gooooogle
[root@localhost ~]# echo gooooogle |grep 'go\{2,5\}gle'\\带表前面的o出现2次以上5次以下
gooooogle
[root@localhost ~]# echo goooooogle |grep 'go*gle' \\表示0次到任意次
goooooogle
[root@localhost ~]# echo gggle |grep "go*gle" \\grep 包含最前面的g不匹配
gggle
[root@localhost ~]# echo gdadadadgle |grep "g.*gle" \\.*代表任意匹配所有
gdadadadgle
[root@localhost ~]# echo ggle |grep "go\?gle" \\ \?一次或者0次
ggle
[root@localhost ~]# echo gogle |grep "go\?gle"
gogle
[root@[root@localhost ~]# echo google |grep "go\+gle" \\一个以上
google
3.位置锚定
^#行首锚定,用于模式的最左侧,
$#行尾锚定,用于模式的最右侧
^PATTERN$ #用于模式匹配整行 (单独一行)
^$#空行
^[[ :space: ]]*$#空白行
\<或\b #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部
\>或\b #词尾锚定,用于单词模式的右侧
#匹配整个单词
[root@localhost ~]# echo hello-123|grep "\<123" 123高亮
hello-123
[root@localhost ~]# echo hello-123|grep "hello\>" hello高亮
hello-123
[root@localhost ~]# grep "^[^#]" /etc/fstab 非#开头的
q
/dev/mapper/centos-root / xfs defaults 0 0
UUID=0cebec14-3506-411d-8257-667162fdb74d /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-var /var xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
bash: q: command not found...
[root@localhost ~]# grep "[^#]" /etc/fstab #开头的
# /etc/fstab
# Created by anaconda on Fri Sep 17 09:34:56 2021
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/dev/mapper/centos-root / xfs defaults 0 0
UUID=0cebec14-3506-411d-8257-667162fdb74d /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-var /var xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
4.分组或其他
分组()将多个字符捆绑在一起,当作一个整体处理,如:(root)+
后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3,…
\1表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
[root@localhost ~]# ifconfig ens33|grep netmask|egrep -o '([0-9]{1,3}.){4}'
192.168.133.50
255.255.255.0
192.168.133.255
二.元字符
.匹配任意单个字符,可以是一个汉字
[]匹配指定范围内的任意单个字符,示例:[zhou][0-g][a-z][a-zA-Z]
[^]匹配指定范围外的任意单个字符,示例:[zhou][Ma.z]a.z
[ : alnum:]字母和数字
[ : alpha:]代表任何英文大小写字符,亦即A-Z,a-z
[ : lower:]小写字母,示例:[[:7ower: ]],相当于[a-z]
[ : upper :]大写字母
[ :blank :] 空白字符(空格和制表符)
[:space:]包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白,比[ :blank:]包含的范围广
[:cntr1:]不可打印的控制字符(退格、删除、警铃…>[ : digit:]十进制数字
[ : xdigit:]十六进制数字
L :graph:] 可打印的非空白字符
[ : print :]可打印字符
[ : punct:]标点符号
\w#匹配单词构成部分,等价于[[:alnum : ]]
\W#匹配非单词构成部分,等价于[[^[ :alnum: ]]``
\S#匹配任何非空白字符。等价于[[^ \f\nkr\t\v]]。
\s#匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\rit\v]。注意unicode正则表达式会匹配全角10
三.扩展正则表达式
grep -E 或者 egrep
-v 取反
-o 匹配
-i 忽略大小写
四.sed命令
1.命令
Sed是从文件或管道中读取一行,处理一行,输出一行;再读取一行,再处理一行,再输出一行,直到最后一行。每当处理一行时,把当前处理的行存储在临时缓冲区中,称为模式空间(PatternSpace),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。一次处理一行的设计模式使得sed性能很高,sed在读取大文件时不会出现卡顿的现象。如果使用vi命令打开几十M上百M的文件,明显会出现有卡顿的现象,这是因为vi命令打开文件是一次性将文件加载到内存,然后再打开。Sed就避免了这种情况,一行一行的处理,打开速度非常快,执行速度也很快
sed [option]... "scripl; stript; . .."[input file.. .]
选项 自身脚本语法 支持标准输入管道
2.选项
-e :直接在命令行模式上进行sed动作编辑,此为默认选项;
-f :将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作;
-i :直接修改文件内容;
-n :只打印模式匹配的行;
-r :支持扩展表达式;
-h或–help:显示帮助;
-V或–version:显示版本信息。
3.sed常用命令
p 打印当前模式空间内容,追加到默认输出之后
Ip 忽略大小写输出
d 删除模式空间匹配的行,并立即启用下一轮循环
a []text 在指定行后面追加文本,支持使用\n实现多行追加
i []text 在行前面插入文本
c []text 替换行为单行或多行文本
w file 保存模式匹配的行至指定文件
r file 读取指定文件的文本至模式空间中匹配到的行后
= 为模式空间中的行打印行号
! 模式空间中匹配行取反处理
q 结束或退出sed
4.查找替代
s/pattern/string/修饰符 查找替换,支持使用其它分隔符,可以是其它形式:s@@@,s###
替换修饰符:
g 行内全局替换
p 显示替换成功的行
w /PATH/FILE 将替换成功的行保存至文件中
I,i 忽略大小写
[root@localhost ~]# sed '' #将输入内容打印出来
123
123
2321
2321
3213
3213
312
312
[root@localhost ~]# sed -n "" #-n就不跟着打印了
23
13
^C
[root@localhost ~]# sed -n "p" #再加上p就又能打印了
12
12
[root@localhost ~]# ifconfig ens33|sed -n "2p" 打印此文件的第2行
inet 192.168.133.50 netmask 255.255.255.0 broadcast 192.168.133.255
5.sed脚本格式
单引号中间需要写脚本;脚本格式如下
'地址+命令’组成
- 不给地址:对全文进行处理(比如行号)
- 单地址:
#:指定的行,$:最后一行
/pattern/:被此处模式所能够匹配到的每一行 - 地址范围:
#,# #从#行到第#行,3,6 从第3行到第6行
#,+# #从#行到+#行,3,+4 表示从3行到第7行
/pat1/,/pat2/
#,/pat/ 从#行开始找到目标为止
/pat/,# 找到#号个目标为止 - 步进:~
1~2 奇数行
2~2 偶数行
[root@localhost ~]# seq 10|sed -n "1~2p"
1
3
5
7
9
[root@localhost ~]# seq 10|sed -n "2~2p"
2
4
6
8
10
[root@localhost ~]# seq 10|sed "2~2d" 删除偶数行
1
3
5
7
9
[root@localhost ~]# seq 10|sed "2d" 删除第2行
1
3
4
5
6
7
8
9
10
[root@localhost ~]# seq 10 >seq.txt
[root@localhost ~]# cat seq.txt
1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# sed -i.bak "3d" seq.txt 操作前先备份
[root@localhost ~]# cat seq.txt
1
2
4
5
6
7
8
9
10
[root@localhost ~]# cat seq.txt.bak
1
2
3
4
5
6
7
8
9
10
##### -a 追加
[root@localhost ~]#seq 10 |sed '2ahehe'
###第二行后追加hehe
[root@localhost ~]#sed -n '/^b/,/^f/p' /etc/passwd 打印b开头到f开头的,如果只有开头,那就全打
### 基本格式 '/表达式1/,/表达式2/p' (不要忘记打印)p 文件名
在使用 sed 命令迁移符合条件的文本时,常用到以下参数.
H:复制到剪贴板;
g、G:将剪贴板中的数据覆盖/追加至指定行;
w:保存为文件;
r:读取指定文件;
a:追加指定内容。
sed ‘/the/{H;d};$G’ test.txt //将包含the 的行迁移至文件末尾,{;}用于多个操作
sed ‘1,5{H;d};17G’ test.txt //将第 1~5 行内容转移至第 17 行后
sed ‘/the/w out.file’ test.txt //将包含the 的行另存为文件 out.file
sed ‘/the/r /etc/hostname’ test.txt //将文件/etc/hostname 的内容添加到包含 the 的每行以后
sed ‘3aNew’ test.txt //在第 3 行后插入一个新行,内容为New
sed ‘/the/aNew’ test.txt //在包含the 的每行后插入一个新行,内容为 New
sed ‘3aNew1\nNew2’ test.txt //在第 3 行后插入多行内容,中间的\n 表示换行
五.awk
功能强大的编辑工具
无交互的情况下实现复杂的文本操作
命令格式
awk选项"模式或条件f编辑指令}文件1文件2
awk -F|-v 脚本文件 文件1文件2
awk用法示例
按行输出文本
按字段输出文本
通过管道、双引号调用Shell命令
逐行读取文本,默认以空格为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令
取硬件使用量
[root@localhost ~]# df|awk '{print $5}'
Use%
12%
0%
0%
1%
0%
2%
1%
2%
1%
0%
[root@localhost ~]# df|awk -F"( +|%)" '{print $5}'
Use
12
0
0
1
0
2
1
2
1
0
[root@localhost ~]# df|awk -F"[ %]+" '{print $5}'
Use
12
0
0
1
0
2
1
2
1
0
取IP和mac地址
[root@localhost ~]# ifconfig ens33|sed -n "2p"|awk '{print $2}' 调出第2行
192.168.133.50
[root@localhost ~]# ifconfig ens33|awk '/netmask/{print $2}' 查找关键字
192.168.133.50
[root@localhost ~]# ifconfig ens33|sed -n "4p"|awk '{print $2}'
00:0c:29:d1:e8:8b
[root@localhost ~]# cat /etc/passwd|awk -F: '{print $1}'
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
[root@localhost ~]# cat /etc/passwd|awk -F: '{print $1":"$5}'
root:root
bin:bin
daemon:daemon
adm:adm
lp:lp
sync:sync
面试题
提取ip地址和时间
58.87.87.99 - - [09/Jun/2020:03:42:43 +0800] “POST /wp-cron.php?
doing_wp_cron=1591645363.2316548824310302734375 HTTP/1.1” ""sendfileon
128.14.209.154 - - [09/Jun/2020:03:42:43 +0800] “GET / HTTP/1.1” ""sendfileon
64.90.40.100 - - [09/Jun/2020:03:43:11 +0800] “GET /wp-login.php HTTP/1.1”
""sendfileo
[root@localhost ~]# cat test.txt|sed "2d"|awk -F"[[ ]" '{print $5":"$1}'
09/Jun/2020:03:42:43:58.87.87.99
09/Jun/2020:03:42:43:128.14.209.154
09/Jun/2020:03:43:11:64.90.40.100
:""sendfileo
[root@localhost ~]# cat test.txt|sed "2d"|awk -F"[[ ]" '{print $1"\t"$5}'
58.87.87.99 09/Jun/2020:03:42:43
128.14.209.154 09/Jun/2020:03:42:43
64.90.40.100 09/Jun/2020:03:43:11
""sendfileo
提取主机名
1 www.kgc.com
2 mail.kgc.com
3 ftp.kgc.com
4 linux.kgc.com
5 blog.kgc.com
[root@localhost ~]# cat host.txt|awk -F"[ .]" '{print $2}' >>host.txt
6.2awk常见的内置变量
FS:指定每行文本的字段分隔符,缺省为空格或制表位。与"-F"作用相同 -v “FS=:”
NF:当前处理的行的字段个数
NR:当前处理的行的行号(序数)
$0:当前处理的行的整行内容
$n:当前处理行的第n个字段(第n列)
FILENAME:被处理的文件名
RS:行分隔符。awk从文件上读取资料时,将根据RS的定义就把资料切割成许多条记录,而awk一次仅读入一条记录进行处理。预设值是\n
[root@localhost ~]# awk -F: 'NR==2,NR==5{print $1}' /etc/passwd
bin
daemon
adm
lp
1.统计/etc/fstab文件中每个文件系统类型出现的次数
[root@localhost ~]# cat /etc/fstab |sed -n '9,$p'|awk '{print $3}'|sort|uniq -c|sort -nr
4 xfs
1 swap
2.统计/etc/fstab文件中每个单词出现的次数
[root@localhost ~]# egrep -o "\b[[:alpha:]]+\b" /etc/fstab|sort|uniq -c|sort -nr
5 dev
5 defaults
4 xfs
4 mapper
4 centos
3 swap
2 var
2 home
2 fstab
2 by
2.awk的条件
- BEGIN
BEGIN 是 awk 的保留字,是一种特殊的条件类型。BEGIN 的执行时机是"在 awk 程序一开始,尚未读取任何数据之前"。
一旦 BEGIN 后的动作执行一次,当 awk 开始从文件中读入数据时,BEGIN 的条件就不再成立,所以 BEGIN 定义的动作只能被执行一次 - END
END 也是 awk 的保留字,不过刚好和 BEGIN 相反。END 是在 awk 程序处理完所有数据,即将结束时执行的。END 后的动作只在程序结束时执行一次。
总结
正则式的用法和总用
awk和sed的使用