正则表达式
用途
对于一些匹配字符串的操作,如果我们使用C++语言,就会非常麻烦。
此时使用正则表达式写个脚本就会非常简单,极大的减少工作量。
比如登录界面匹配用户名,密码,使用正则表达式判断是否符合基本规范就会非常简单。
在C++程序中嵌入其它语言写的程序在网络编程部分会提到的,这是一个非常重要的模块。
例如, 在读取日志文件时,日志文件常常非常大,50g以上,此时vim就失去了效果,因为使用vim打开日志文件会将文件加载到内存中,导致内存溢出,程序崩溃。
此时我们用正则表达式选取我们需要的内容就会非常方便,因为日志文件都是非常规律的,正好正则表达式发挥。
大多数脚本语言都已经包含了正则表达式,这些脚本语言本身就可以对字符串方便的进行匹配。
正则表达式的符号
基础正则:^, $, ., *, []
扩展正则:+, |, (), {}, ?
基础正则是正则表达式诞生时就有的,扩展正则是正则表达式在后续发展进程中逐渐加入的。
' '和" "
' '或" "表示整体。正则表达式一定要用' '或" "扩起来,否则极其容易出现错误。
正则表达式中,' '和" "没有区别,但在某些语言中," "会带来各种各样的错误,比如perl,php和接下来要讲的awk,awk可以算作一种语言。
grep命令
介绍
在文件中匹配字符串,然后把满足条件的行打印出来。
常用参数
grep的参数非常多,但常用的就三个。
-i:ignore的简写,表示忽略字母的大小写。-v:invert的简写,表示输出文件未被匹配的行。-n:number的简写,表示输出文件的行号。
使用示例
grep -n int test.cpp在test.cpp文件找到包含int的行 -n表示行号grep -nv int test.cpp在test.cpp文件找到不包含int的行 -n表示行号
基础正则
| ^ | $ | ^$ | . | * | .* | [] |
|---|---|---|---|---|---|---|
| 以...开头 | 以...结尾 | 空行 | 任意字符 | 前一个字符连续出现0次及以上 | 所有行 | 括号中的任意一个 |
讲一下正则的贪婪性,对于正则表达式,在表示连续出现时,会匹配尽量多的字符串。
[0-9]表示任意数字,[a-z]表示任意小写字母。[a-zA-Z]表示任意大小写字母
注意:中括号中的特殊字符将不会被当做特殊字符处理
扩展正则
+:表示前面的符号出现了至少一次|:表示或者,和[]的区别就是|匹配的是单词,而[]匹配的是单个字符():被()括起来的字符串。会被解释为一个整体。{m, n}:表示前面的字符连续出现了m到n次?:表示前一个字符出现0次或1次
常用范例
这里主要是讲几个比较常用的转义字符。
\s: 表示任意多个空格字符(包括空格和\t)\S: 表示不是空白的字符\w: 表示[0-9A-Za-z_],\w就是个简写\W: 和\w相反,表示不是[0-9A-Za-z]的字符\b: 表示单词的结束(注意,\b并不占据位置进行匹配,它只检测接下来的字符是否为\w)
注意:还有一个比较常用的转义字符\d,代表[0-9]。但是grep命令并不支持,这个转义字符在perl语言中是支持的。
对于运维人员来说,有时需要写一些比较复杂的正则表达式。比如email格式,url格式,xml格式这些。我们开发人员只需要掌握一些简单的正则表达式就可以了,其实正则表达式不会很难,最多只是长一些罢了。
如果大家想要练习自己的正则表达式水平,直接百度:常见的正则表达式范例,没事干多看一看,积累一下就可以了。
sed命令
解释
对文件按行进行遍历,依次对这些行进行操作。sed就是stream editor的简写,意为对每一行以流的形式进行处理。
执行过程
sed的执行过程很简单,就是每次向进程中加载一行。如果对这一行没有任何修改,则直接将这一行输出,使用-n参数可以不输出未经修改的行。
功能
增加 三种标识符 c:替代(replace)
sed -r 's/old_text/new_text/' filename.txta:追加:(append)在下一行追加
sed '/pattern/a\This is an appended line.' filename.txti:插入:(insert)在上一行插入
sed '/pattern/i\This is an inserted line.' filename.txt增加部分总结:这部分用的比较少,但还是应该尽量掌握。
删除 标识符为d
按照行数删除
sed -r '1,3d' num.txt # 删除1到3行 其余输出出来按照范围删除
sed -r '/2022-01-01 10:10:00/,/2022-01-01 10:10:10/d' num.txt这部分用的比较少,尽量掌握就可以了。
修改 标识符为s 基础用法
sed 's/old_text/new_text/' filename.txts配合"()"的用法
sed -r 's/(pattern)/replacement/g' filename.txt这部分非常常用。尤其在处理一些规律性的文本时更是极其方便,一定要会。
查找 标识符为p 按照行数查找:
sed -n '1,10p' num.txt # 输出1到10行按照内容查找
sed -n '/pattern/p' filename.txt查找部分最重要的就是按照内容查找,日志文件中经常使用,//中是可以支持正则表达式的,但一般这里用不到正则表达式。
awk命令
介绍
(1)awk是一种语言,它有一套完整的语法,内容十分丰富的,有专门的书去系统的讲awk。专门买一本书去学awk是完全没有意义的,我们只要会一些基本的操作就可以完成基本任务了,如果有需要,可以遇到问题再去积累,这样效率远比看书高。 (2)awk的名字源于发明这门语言的三个人的名字。这点了解一下就可以了。
执行过程
- 先执行BEGIN指令
- 判断每行是否满足条件,若满足条件,进行操作。
- 最后执行END指令
awk -F: 'BEGIN{print "this is BEGIN"}NR==1{print $1}END{print "this is END"}' num.txt任意一个部分都可以省略,条件判断部分也可以省略。
注意:这里的NR为number of record的简写,在awk中,record也表示行的含义,直接翻译过来就是记录。
$ n表示第n行,$0表示全行,$NF代表最后一行
常用的参数
(1) -F可以设置选取列时的分隔符,默认为\s (2) -v OFS=可以设置显示的列的分隔符,默认为空格
awk -F: -v OFS=: '{print $1,$2,$3,$4}' num.txt常用内置变量
(1) NR:之前例子中使用的NR就是awk最常用的内置变量。 (2) NF:表示一行的最后一列,nember of field的简写,在awk中field表示列、
判断条件:
- NR进行条件判断,可以使用
,,&&,|| - 可以使用传统的
//判断范围
awk -F: '/2022-01-01 10:10:00/,/2022-01-01 10:10:10/' num.txt- 可以对某一列单独进行处理,这个用法很重要,弥补了grep的不足
awk -F: '$5~/^s/' num.txt # 打印每一行第五列若满足什么则打印出来BEGIN和END的用法:
(1) awk是一门语言,一门语言是可以计算的。 (2) BEGIN用的相对比较少,BEGIN可以定义变量,进行不涉及文件的统计,但awk一般只进行简单的操作,这部分用的比较少。 (3) END用的就比较多了,因为我们经常在END中计算,然后输出结果。
- 统计文件有多少行
awk '{sum++}END{print sum}' num.txt- 统计某一列的和
awk '{sum+=$4}END{print sum}' num.txt #每一行第四列总结一下awk命令:awk是一种语言,严格来说,awk的功能其实非常多,但一般来说,这些操作就够用了,再复杂的操作就不适用awk来完成了。
总结
- grep擅长过滤,命令格式最简单方便。
- sed擅长按行的形式进行处理,比如范围过滤,替换,增加,删除。
- awk删除对列进行过滤,计算,对比等操作。
- 从命令的复杂程度考虑,awk > sed > grep。
- 所以我们一般优先考虑grep,然后是sed,再之后是awk。
- 我们以后在处理文件时,要合理的使用这三个命名,这三个命令很常用,也很重要。
