这是一篇关于正则表达式的文档,如果你是Linux系统管理员,那么你一定离不开它(正则表达式)了,
它可能出现在 grep/more/less/man/vi(m)/sed/awk/apache/nginx/haproxy 等等与linux 系统相关的地方,所以掌握正则表达式对于linux系统管理员很重要!
一 什么是正则表达式?
正则表达式是一种表示方式,让你可以查找匹配特定规则的文本
二 正则表达式分两类
1 BRE 基本正则表达式(Basic Regular Expression)
2 ERE 扩展正则表达式(Extended Regular Expression)
三 正则表达式由两部分组成
正则表达式由两部分组成,一般字符与特殊字符
1 一般字符,指的是没有任何特殊意义的字符,比如 abcdef123456等等用于表示其自身
2 特殊字符,又称为元字符(metacharacter),见下表
POSIX BRE 与 ERE 元字符表
- 字符 BRE/ERE 模式含义
- \ 两者均可 关闭后边元字符的特殊意义
- . : 匹配任意单个字符,但换行符除外
- * : 匹配在它之前的重复任意次数的单个字符(包括0次,没有匹配)
- ^ : 匹配紧接着的正则表达式,在行手或者字符串的起始处
- $ : 匹配前面的正则表达式,在行尾后者字符串结尾处
- [...] : 匹配方括号内的任意字符,方括号内包含 - 连字符表示范围,^(第一位)表示取反
- \{n,m\} BRE 区间表达式,匹配在它前面的单个字符重复区间次数,1至9次;5次;1,至少1次
- \( \) BRE 后向引用,第一步将子表达式放在 \( 与 \)里,最多9个子表达式
- \n BRE 后向引用,第二步使用匹配的子表达式,如 \1,后向引用用于查找重复字,以及匹配引号时特别好用,如\(["']\).*\1,匹配单引号或者双引号括起来的子.
- {n,m} ERE 区间表达式与BRE相比少了反斜杠
- + ERE 匹配前面的正则表达式的一次或者多次
- ? ERE 匹配前面的正则表达式的一次或者零次
- | ERE 匹配|符号前或者后的正则表达式
- () ERE 匹配使用括号括起来的正则表达式群
四 正则表达式的优先级
正则表达式的优先级,指的是某个运算符根据优先级高低,将优先处理
- 1 BRE 优先级(由高至低)
- 运算符 含义
- [..] [==] [::] 用于字符排序的方括号符号
- \metacharacter 转义的元字符
- [ ] 方括号表达式
- \( \) \digit 子表达式与后向引用
- * \{ \} 重复前置的单个字符
- 无符号 连续的字符
- ^ $ 锚点
- 2 ERE 优先级(由高至低)
- 运算符 含义
- [..] [==] [::] 用于字符排序的方括号符号
- \metacharacter 转义的元字符
- [ ] 方括号表达式
- ( ) 分组
- * + ? {} 重复前置的正则表达式
- 无符号 连续的字符
- ^ $ 锚点
- | 交替
五 BRE 与 ERE 的不同
BRE 与 ERE 在大多数的元字符与功能应用上几乎是完全一致的,但是ERE里有些元字符看起来与BRE类似,却具有完全不同的意义
1 匹配单个字符;
ERE与BRE基本一致,比如一般字符,用于转义的反斜杠,以及方括号表达式
2 ERE中不存在后向引用;
圆括号在ERE中表示分组,而\( \)在ERE中表示匹配左括号与右括号
3 匹配单个表达式与多个正则表达式
ERE在匹配多字符这方面与BRE有很明显的不同(*处理方式上除外),比如 区间表达式不在需要使用反斜杠,而 ? 与 + 元字符可以更细腻的匹配控制
4 BRE中没有交替与分组
与BRE不同ERE中拥有交替字符"|",用于匹配多个字符序列,比如 one|two|three|four ;
同上,ERE拥有分组"()",用于表达式群,比如 (one)+ 用于匹配一个或多个连续的one ;
组合使用,如 this is (one|two) 或者 this is (one|two)* 匹配0个或多个one 或者 two;
5 停驻文本匹配(锚点)
"^"与"$" 在 BRE与 ERE表示的意义是相同的,需要注意的是它们在方括号表达式中将会失去它们的特殊意义;
组合使用,如 this is ^(one|two)$ 匹配one 或者 two
六 额外的GNU表达式运算符
- 运算符 含义
- \w 匹配任何单词
- \W 匹配任何非单词
- \< \> 匹配单词的起始或结尾
- \b 匹配单词的起始或结尾处,所找到的空字符串
- .....
七 简单例子
- 1 sed
- sed -r 's\|[ ]*//g'
- sed -r 's/[ ]+//g;s/^\||\|$//g' variables (注意 g 全局替换,如果不是用g 将只匹配每行的第一个)
- sed -r 's/[ ]+//g;s/(^\|)|(\|$)//g' variables (注意 ()分组 与没有使用括号分组,完成的功能一样)
- sed -r 's/\|[ ]//g;s/[ ]*\|$//g' variables
- sed -r 's/([ ]+)?\|//g;s/ //;/\+/d' variables
- sed -re 's/(\|)//g' variables | sed -e 's/[ ]\{2,\}/ /g' | sed -e '/^\+.*/d'
- sed -rf sed.sed variables
- cat sed.sed
- s/(\|)//g
- s/[ ]{2,}/ /g
- /^\+.*/d
- s/^( )|( )$//g
- 2 vim
- :10,$ s/^[\t]*/ / #行头所有换行符,用空格替换
- :10,30 s/^[ ]*/ / #行头有多个空格,用一个空格替换
- :10,30 g/^ *$/d #删除空行
- :10,20 s/[#].*/ / ##号后边的任意位字符串,用一个空格替换
- :6,9 s/^[ ]// #行头空格删掉!
- :1,$ s/\\n// #\n 删掉!
- :1,$ s/^[ ]//
- :10,20 s/[ ]\{2,\}// #重复两次以上的空格,删掉!
- :7,20 s/^/echo "/
- :7,20 s#$#\" >> /etc/rsyncd.conf# 分隔符是#,每行后添加 " >> /etc/rsyncd.conf
- :6,20 s/^/ / #行头添加俩个空格,注意 中间有俩空格!
- :% s/^/#/g #每行前添加#号,如果每行尾添加则^变成$即可,%表示全文!
- :% s/\(\d\+\.\)\{3\}\d\+//g #去掉 ip 地址(10.0.0.1)
- # 1. #!/bin/sh #空白为 空格
- .....
- 31. done #空白为 tab
- :% s/^\s\{2,\}\d\+\.//g #替换开头为空白或者tab ifs字符至少重复两次以上,接数字至少重复一次,接.号,全局替换
- # [url]com[/url]
- :% s#\[url\]\|\[/url\]##g #替换 [url]或者[/url],注意 \| 表示或者
sed 杂记 20120606
- [root@linux ~]# sed [-nefr] [动作]
- 参数∶
- -n ∶使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN
- 的资料一般都会被列出到萤幕上。但如果加上 -n 参数后,则只有经过
- sed 特殊处理的那一行(或者动作)才会被列出来。
- -e ∶直接在指令列模式上进行 sed 的动作编辑;
- -f ∶直接将 sed 的动作写在一个档案内, -f filename 则可以执行 filename 内的
- sed 动作;
- -r ∶sed 的动作支援的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
- -i ∶直接修改读取的档案内容,而不是由萤幕输出。
- 动作说明∶ [n1[,n2]]function
- n1, n2 ∶不见得会存在,一般代表『选择进行动作的行数』,举例来说,如果我的动作
- 是需要在 10 到 20 行之间进行的,则『 10,20[动作行为] 』
- function 有底下这些咚咚∶
- a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
- i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
- c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
- d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
- p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
- s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配
- 正规表示法!例如 1,20s/old/new/g 就是啦!
- sed替换(WWW换成WEB)
- sed -ri 's/(COMPILE_INITS=).*/\10/' /install/ghostscript-8.63/Makefile (选项 -r 使用扩展正则表达式)
- sed -i 's/WWW/WEB/' dd.txt (匹配 WWW 用 WEB代替)
- sed -i "s/^/''/g" one.txt (注意 单引号与双引号,匹配每一行,把'' 添加到 行头部!)
- sed -i 's/.*index.html/DirectoryIndex index.html index.htm index.php/' /usr/local/apache/conf/httpd.conf
- sed -i '/AddType application\/x-gzip .gz .tgz/a\ AddType application\/x-httpd-php .php' /usr/local/apache/conf/httpd.conf
- (注意 a\ 在匹配这行之下添加一行!)
- sed -i '/export/a export PATH=$PATH:/usr/local/apache/bin' /etc/profile (别忘了 source /etc/profile)
- sed -n '/.*index.html/p' /usr/local/apache/conf/httpd.conf (.*捡破烂模式)
- sed -n '/\/usr\/local.*\/bin/p' /etc/profile
- sed -i '/\/usr\/local.*\/bin/d' /etc/profile
- sed -n '/\/usr\/local\/.*/p' /etc/ld.so.conf
- sed -n '/bz-clone/p' /etc/hosts
- 127.0.0.1bz-clone.test.com bz-clone localhost.localdomain localhost
- sed -i 's/bz-clone/cl3/g' /etc/hosts (注意 g 全局替换,如果不是用g 将只匹配每行的第一个)
- 127.0.0.1cl3.test.com cl3 localhost.localdomain localhost
- sed -n 's/^#/shell>/p' sed.txt ()
- sed -n 's/^#/shell>/p' sed.txt
- sed -i 's/^#/shell>/' sed.txt
- sed -n '/^ $/p' sed.txt
- sed -n '/^ $/d' sed.txt (注意 d 删除匹配这行)
- sed -r '/^sda/d' test1 d 删除^sda行
- sed -i '/^ $/d' sed.txt
- sed -n '/shell>/p' sed.txt
- sed '/shell>/i\ ' sed.txt
- sed -i '/shell>/i\ ' sed.txt (注意 i\ 在匹配这行之上添加一行!)
- sed '1 d' test
- sed '1,2 d' test
- sed -rn 's/[0-9 \t]+//p' a.txt
- bbb [ESXI] 10.0.0.1 10.0.0.2 DELL R910 SJHL E7520*1.86GHz*4/300G*4/32G
- | Uptime | 325453 |
- | Uptime_since_flush_status | 325453 |
- sed -r 's\|[ ]*//g'
- sed -r 's/[ ]+//g;s/^\||\|$//g' variables (注意 g 全局替换,如果不是用g 将只匹配每行的第一个)
- sed -r 's/[ ]+//g;s/(^\|)|(\|$)//g' variables (注意 ()分组 与没有使用括号分组,完成的功能一样)
- sed -r 's/\|[ ]//g;s/[ ]*\|$//g' variables
- sed -r 's/([ ]+)?\|//g;s/ //;/\+/d' variables
- sed -re 's/(\|)//g' variables | sed -e 's/[ ]\{2,\}/ /g' | sed -e '/^\+.*/d'
- sed -rf sed.sed variables
- cat sed.sed
- s/(\|)//g
- s/[ ]{2,}/ /g
- /^\+.*/d
- s/^( )|( )$//g
- (感慨 )
- sed -in '$d' /etc/rc.local (注意 $ 最后一行)
- sed -r 's/(1.)|(2.)//g' en.txt | sort -n > tmp
- sed '/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile (这不是我想要的,在每一个export行,添加新的)
- sed '61,/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile (61, 为限定第61行)
- sed '$,/export/ a\export PATH=$PATH:/usr/local/subversion/bin' /etc/profile (注意 $ 最后一行)
- sed -i '$ a\/usr/local/apr-util/lib' /etc/ld.so.conf (在最后一行添加一行文本)
- sed -ri '/^$/d;s/(^[ \t]+)//g;' /var/www/rsync/rsync_file.list #-r拓展正则表达式,-i直接替换
本文出自 “dongnan” 博客,转载请与作者联系!