心得:
今天写一篇关于正则表达式用法的内容,绝对通俗易懂,希望把自己学到的东西,在这里能记录下来,以我自己理解的方式表达出来,相信更多人能学会。而且shell的正则类似于python正则,学会了一个相当于学会两种哦~
3正则表达式用法
正则表达式一般用于字符的匹配,关键字的筛选,对文本的一系列操作。好比我们文本查找的功能,Command F可以查找匹配到的所有关键字,并标记出来,正则不仅可以匹配关键字,还能匹配格式。可以解决99%的文本问题。
dog.py 原文,以下例子会以它为原型进行匹配练习:
tianjain@tianjain-TM1701:~$ cat dog.py
import os
class Dog():
def __init__(self,name,age):
self.name=name
self.age=age
def sit(self):
print(self.name.title()+" is now sitting")
def roll_over(self):
print(self.name.title()+" rolled over")
# my_dog=Dog("willie",6)
# my_dog.sit()
# print(my_dog.name+" "+str(my_dog.age))
print("s")
匹配进程,通过管道直接匹配自己想要的进程
tianjain@tianjain-TM1701:~$ ps -ef | grep "main"
tianjain 22054 20770 0 20:23 pts/23 00:00:00 grep --color=auto main
匹配文本关键字,通过管道匹配文本关于def的内容
tianjain@tianjain-TM1701:~$ cat dog.py | grep def
def __init__(self,name,age):
def sit(self):
def roll_over(self):
匹配格式,我匹配了以坐括号为开始,结尾是点,中间是4个字符的格式去匹配,符合要求的就两行内容。当然这只是比较粗浅的匹配,目的是想让大家记住这个格式。双引号里的内容,其实和我们用的公式类似,相应的格式填入,就会匹配你需要的字符或者格式。[匹配的内容 匹配的次数]
tianjain@tianjain-TM1701:~$ cat dog.py | grep "([a-zA-Z]\{4\}\."
匹配的内容:
print(self.name.title()+" is now sitting")
print(self.name.title()+" rolled over")
基本组成:
正则表达式 | 描述 |
---|---|
\ | 转义符 忽略特殊字符意义 |
^ | 匹配行首 ^def |
$ | 匹配行尾 def$ |
. | 匹配单个任意字符 tia. |
[] | 匹配内部的任意一个字符,可匹配tia 也可匹配tin ti[an] |
[^] | 匹配内之外的字符,匹配除an之外的字符 [^an] |
[-] | 匹配范围字符,匹配数字1到5 [1-5] |
? | 匹配一次或者零次 a? |
* | 匹配零次或者无数次 a* |
+ | 匹配一次或者无数次 a+ |
{m} | 匹配m次 a{5} |
{n,m} | 匹配最少n次,最多m次 a{1,3} |
| | 匹配两边任意一项 ab(c|d) |
元字符
表达式 | 描述 |
---|---|
\b | 单词边界,匹配better单词 \bbetter\b |
\B | 非单词边界,匹配不以b开头的etter单词 \Bbetter |
\d | 匹配单个数字 |
\D | 匹配非数字字符 |
\w | 字母或者数字 |
\W | 非字母和数字 |
\n | 换行 |
\s | 单个空白字符 |
\S | 单个非空白字符 |
\ r | 回车 |
\f | 换页 |
\t | 横向制表符 |
\t | 垂直制表符 |
匹配数字:^[0-9]$ 或者 \d
匹配负数:^-\d+$
匹配小数:^[0-9]+.[0-9]+$
tianjain@tianjain-TM1701:~$ cat dog.py | grep "^[0-9]\+\.[0-9]\+$"
43.43
匹配字符串: ^[0-9a-zA-Z]\+
tianjain@tianjain-TM1701:~$ cat dog.py | grep "^[0-9a-zA-Z]\+"
import os
class Dog():
匹配邮箱:^\w+@\w+.[a-z]+
tianjain@tianjain-TM1701:~$ cat dog.py | grep "^\w\+@\w\+\.[a-z]\+"
309111985@qq.com
匹配手机号码:
tianjain@tianjain-TM1701:~$ cat dog.py | grep "[0-9]\{3\}-[0-9]\{4\}-[0-9]\{4\}"
175-2105-0772
匹配网址:
tianjain@tianjain-TM1701:~$ cat dog.py | grep "https://\w\+\.\w\+\.\w\+\(/\w\+\)*"
https://mp.csdn.net/mdeditor/100369595
https://blog.csdn.net/qq_45503700
只要是文本格式的内容基本上都可以匹配到,具体的用法需要多多练习,才能熟练掌握。接下来讲讲正则常用到的几个通道命令用法:
3.2 grep用法
通道去匹配到的关键字
(1)-i:忽略搜索字符串的大小写
(2)-v:取反,即输出不匹配的那些文本行
(3)-n:输出行号
(4)-l:输出能够匹配模式的文件名,相反的选项为-L
(5)-q:静默输出
3.3 sed用法
常用的就是sed替换的方法: sed ‘s/被替换字符串/新字符串/g’,可以删除不需要的字符包括空白,特殊字符,都可以用正则来匹配。
tianjain@tianjain-TM1701:~$ echo "Hello world"
Hello world
tianjain@tianjain-TM1701:~$ echo "Hello world" | sed 's/world/tian jian/g'
Hello tian jian
tianjain@tianjain-TM1701:~$
sed 结合正则
tianjain@tianjain-TM1701:~$ cat dog.py | grep "^[0-9]\+\.[0-9]\+$"
43.43
tianjain@tianjain-TM1701:~$ cat dog.py | grep "^[0-9]\+\.[0-9]\+$" | sed 's/^[0-9]\{2\}//g'
.43
tianjain@tianjain-TM1701:~$
3.4 awk 用法
匹配
$0代表该行全部字数,$1代表用空格或TAB隔开的第一个字段,以此类推,显示列数
tianjain@tianjain-TM1701:~$ cat dog.py | awk '{print $1}'
import
class
每一行都会去执行{print $1},-F 指定域分隔符
#cat /etc/passwd |awk -F ':' '{print $1}'
root
daemon
如果只是显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以逗号分割,而且在所有行添加列名name,shell,在最后一行添加"blue,/bin/nosh"。
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
name,shell
root,/bin/bash
daemon,/bin/sh
bin,/bin/sh
sys,/bin/sh
....
blue,/bin/nosh
awk工作流程是这样的:先执行BEGING,然后读取文件,读入有/n换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域, $1表示第一个域,$n表示第n个域,随后开始执行模式所对应的动作action。接着开始读入第二条记录······直到所有的记录都读完,最后执行END操作。
附录:
十六进制位提取
假设你有一个十六进制的数,你需要用到EF位置的数字你该怎么去提取呢,正则sed提取算一种方法,然而我讲的是另外一种方法:
n=0x89ABCDEF 成功将EF提取出来并转换为十进制
tianjain@tianjain-TM1701:~$ m=$((n&0x000000FF))
tianjain@tianjain-TM1701:~$ echo $m
239
如果我们需要提取CD位置的十进制数呢
tianjain@tianjain-TM1701:~$ n=0x89ABCDEF
tianjain@tianjain-TM1701:~$ m=$((n>>8 & 0x0000FF))
tianjain@tianjain-TM1701:~$ echo $m
205
先将十六进制数移两位,然后再进行与运算
问题注意点:shell中换行符问题
当出现错误为:syntax error : invalid arithmetic operator时,代表字符串中存在\r,linux系统中换行只存在\n,所以在运算时会出现以上问题,解决方法如下:
利用正则取出空格~
sed 's/\s//g'
echo 打印换行方法:
出现-e参数代表\n换行生效
echo -e "Hello \nWorld"