正则表达式 linux shell
热身正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。 例如 grep,expr,sed,awk. 或Vi中经常会使用到正则表达式,为了充分发挥 shell 编程的威力,需要精通正则表达式。 下面先举个简单例子来让大家对正则表达式有个直观的感受。ls命令是linux下最常用的命令。ls命令是list的缩写,缺省下ls用来打印出当前目录的清单。 现在,我们只希望列出以d开头的文件或目录,可以用ls d* 命令,这里*是通配符,它表示匹配重复零次或多次前一字符。 举一反三,列出以che 开头的文件或目录,就可以用ls che* 命令。 是不是觉得有些觉得过于简单了啊??!!好吧,打完小怪,现在升下级。 开始…… 如何列出当前目录下的所有目录(不包含下面的子目录)? 思考…… 到了使出正则表达式杀手锏的时候了,在这里,我们还是使用ls 命令,但是加了个 -l选项(-l选项作用是列出文件的详细信息),使用正则表达式列出当前目录下的所有目录,我们给出了两种方法(聪明的你当然会想到也可以用find命令,呵呵,这属于第三种秘笈了)。且看: 这样列出来的内容有些多,没完全截下来所有显示结果,但这并不妨碍本文的讲解。 考虑到普通文件是以-开头,如dataf1.txt文件;目录是以d 开头的,如 adv_shell 是目录,即第一个字母会不小心暴露出文件的身份属性。 所以我们就从d这里作为突破口,这时,你会想到,有多少个“开头”的d就应该有多少个目录,太聪明了,好吧,我们按照你的思路实践下。 现在,问题出来了,怎么统计出来有多少个“开头”的d?你想到了linux中grep命令,还想到了正则表达式,于是grep和正则表达式开始粉墨登场了…… ls -l |grep “^d” 这条简单的命令就轻松解决了我们的问题,。”^d”???你纳闷了,这个小东西配合起来怎么会有那么大的威力呢?这好比玩三国杀时刘备、司马懿、香香之间配合的威力……”^d”,就是正则表达式的用法,”^”表示匹配行首,”^d”合起来就表示以d开头的一行,grep “^d” 就是过滤出以d开头的那些行,d 表示目录,也就过滤出了当前目录中的所有目录。 谜底解开。现在你又想到,前面不是说还有一种方法的么,既然如此迫不及待,那就只好顺水推舟了。 第二种方法还是基于ls命令,但是用了-F 选项,-F 选项能列出文件类型的指示符号,如下图所示: 仔细观察我们发现,在文件名后面,会多出了一些符号,如目录adv_shell名字后多了条斜扛(/),可执行文件checkhost.sh名字后多了个星号(*)……在此,如果想更多了解这些符号意义,可以查看ls 命令的详细信息。 我们现在把注意力集中到目录adv_shell名字后多了条斜扛(/)这条信息上。很快联想到,有多少个斜扛(/)就应该对应多少目录,而且斜扛(/)会跟在每个目录名的最后。我们又想到了grep命令,还想到了应该怎样用正则表达式表示出匹配行尾,答案已经很接近了…… ls -F | grep “/$” 这条短命令又一切成全了我们的梦想。”/
在此基础上,我们发散一下思维,比如说想统计当前目录下的文件个数及目录个数,就可以使用以下命令: ls -l * |grep “^-“|wc -l ls -l * |grep “^d”|wc -l 好了,暂且休息,下面我们开始介绍更多关于正则表达式的知识。 蓄势前面我们初识了^ $ * 这些个正则表达式的用法,下面我们将进行更高一级的升炼。 正则表达式是一个字符或和元字符组合成的字符集,它们匹配(或指定)一个模式。字符即普通字符(例如字符 a 到 z),元字符即特殊字符(例如前面提到的字符 ^ $ *)。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。 在这里,为简单见,我们不会介绍所有的正则表达式知识,只介绍常用的一些正则表达式知识。 一个正则表达式包含下面一个或多个项: 1.一个字符集 这里的字符集里的字符表示的就是它们字面上的意思.正则表达式最简单的情况就是仅仅由字符集组成,而没有其他的元字符。 2.锚 一个锚指明了正则表达式在一行文本中要匹配的位置,例如^和$就是锚。 3.修饰符 它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围.修饰符包括了星号、括号和反斜杠符号。
翱翔部分例子 /b([a-z]+)1b/gi 一个单词连续出现的位置 /(w+)://([^/:]+)(:d*)?([^# ]*)/ 将一个URL解析为协议、域、端口及相对路径 /^(?:Chapter|Section) [1-9][0-9]{0,1}$/定位章节的位置 /[-a-z]/ A至z共26个字母再加一个-号。 /terb/ 可匹配chapter,而不能terminal /Bapt/ 可匹配chapter,而不能aptitude /Windows(?=95 |98 |NT )/ 可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次的检索匹配。 下面来些更加高级些的例子。 对于vi 中命令的分析 s/.?$n^.*$/1/g 初一看,会傻眼,眼前感觉全是$^.*/……这些符号的闪动。 不要紧,下面慢慢道来。 先给出vi中替换命令的格式。 s/re/string 用string替换正则表达式re 如果在后面加了个g 如: s/re/string/g 表示表示对该行内符合模式的进行全部替换。 例如,s////g 这个正则表达式就表示,对行内所有的斜扛(/)替成下划线(), /即替换命令格式中的re,用反斜扛是为了转义, /即表示 / 的本意;_即替换命令格式中的string。 好了,了解vi中替换命令的格式后,我们再对细节进行分析。 前面介绍到 … 表示正则表达式分组,n表示第 n 个分组内容,于是对于 s/.?$n^.*$/1/g 中的 1 ,就表示第一个正则表达式分组即.?
类推,2就应该表示第二个正则表达式分组,即 n^.*
好了, %s/.?$n^.*$/1/g 就可以写为: s/AB/A/g 作用就是将行内所有的AB都替换成A。 现在我们来分别分析A和B的作用。 A=.?$ 抽取出来实际上是…,表示正则表达式 分组,再分析括号内的^.*
B=n^.*$ 分析: n换行,^.*$同上,表示匹配这一行,综合起来就是:下一行(即上行结束后开始的另一行)。 再于是就有:%s/AB/A/g 即将所有AB都替换成B ,代入A和B各自意思得到: 将两行(如行1和行2 )内容替换为第一行内容(即行1的内容),加上/g,就是对全文进行前述替换,也就是隔行删除,如果是从文件第一行开始进行的操作,就意味着是删除所有偶数行、保留所有奇数行操作。 从上面的分析过程中,我们总结出两条有用的正则表达式: %s/.?$n^.*$/1/g 删除偶数行 %s/^.*$n.?$/1/g 删除奇数行 不过瘾的话,还可以再看看另一例子: sed 's/.?.$/2/' 2就应该表示第二个正则表达式分组 同上,也将A=/.?,B=.$,表达式变为’s/AB/B’,将AB都替换成B 。 分析A、B作用。 A=/.? 抽取出来实际上是…,表示正则表达式 分组,再分析括号内的 .*,表示匹配任意零个或多个字符 ( 除换行符 ) B=.$ 括号内的 . ,表示匹配任意字符(除换行符),括号外的$表示匹配到行尾,即表示行尾的最后一个字符;那上述的A /.? 就表示该行最后一个字符前的所有字符。 于是sed ‘s/.?.$/2/’ 作用就是:删除该行除最后一个字符外的所有字符,保留最后一个字符,也即取得该行最后一个字符。 好了,正则表达式的介绍就告一段落,知识点比较多,需要平时反复的积累,遇到复杂的正则表达式时首先要克服恐惧的心理,然后按照上面的方法化繁为简,抓住其本质的东西,有如探囊取物,必手到擒来。 转载注明出处。 —End— (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Flash获取url ,ExternalInterface使用
- ruby-on-rails – 为什么Google Bot抓取不存在的CSS文件?
- 2013年工作中遇到的20个问题:201-220
- c – 使用unique_ptr和shared_ptr进行奇怪的段错误
- Flex version4locale问题
- Flex TextArea组件简单应用:文字链接,图片显示,字体设置
- objective-c – 在自定义框架中添加自定义框架
- Cocos2d-x之Ref、AutoreleasePool、PoolManager
- cocos2dx自学之 事件监听
- iphone – 使用Xcode创建无线清单文件(.plist Extension)