【那年那人那linux】“正则表达式”初窥之二则问题

    始于linux学习过程中欲检测学习效果,同学推荐了两道正则表达式的题目。这两道题目字数不多,但却引发了我的一段思考。操作环境CentOS6.7 2.6.32-573.22.1.el6.x86_64

    现题目整理如下:

    【第一则

    请使用正则表达式与sed命令将/etc/passwd内的第一个单词与最后一个单词置换。例如:

sc:x:891:809::/home/sc:/bin/bash #操作之前
bash:x:891:809::/home/sc:/bin/sc #操作之后

    【第二则

    请使用正则表达式与sed命令将/etc/passwd内的第一组数字与最后一个单词置换。

sc:x:891:809::/home/sc:/bin/bash #操作之前
sc:x:bash:808::/home/sc:/bin/890 #操作之后


    解答

    首先来看第一则.

    首先,我们的主要目标提取第一个单词和最后一个单词,观察单词的特点,纯字母形式,故可以表示为(^[a-zA-Z]*)和([a-zA-Z]*$);

    第二步,把剩余的部分看作一个整体,观察特点,我们会发现剩余部分是两个“:”之间的部分,于是可以想到冒号开头、冒号结尾,紧接着,为了完整的表示出这个部分,我们可以使用([^a-zA-Z].*[^a-zA-Z])(如此,三个部分表示完毕);

    最后根据sed命令替换的规则,辅以后向引用“\3\2\1”,完成操作!下面贴上命令行:

[root@oldboy ~]# sed -r 's#(^[a-zA-Z]*)([^a-zA-Z].*[^a-zA-Z])([a-zA-Z]*$)#\3\2\1#g' /etc/passwd
bash:x:0:0:root:/root:/bin/root
nologin:x:1:1:bin:/bin:/sbin/bin
......
bash:x:889:807::/home/sa:/bin/sa
bash:x:890:808::/home/sb:/bin/sb
bash:x:891:809::/home/sc:/bin/sc
[root@oldboy ~]#


    小结:我们对文件内容的每一行进行分析,结果发现,按照题目要求可以将一行文字分为,“单词--两个非字母之间的部分--单词”。按照这个模式,我们以单词为用力点,将语句完美分隔开了,shell也没有识别错误。


    再来看第二则,这道题目是上一题的升级版本,乍一看可以用是第一题的模式来解题。我们先来整体分析,寻找一下思路。


    整体分析:按照题目要求需要调换第一组数字和最后一个单词,由上一题的分析得出,我们可以选择从数字和单词这两点着手实验。我们可以观察出下面这个模式“非数字部分--第一组数字--非字母之间的部分--最后一个单词”。从shell执行解析正则表达式的顺序, 上面这一模式是正确的,能够完整表示出一行的内容。下面贴上命令行:

[root@oldboy ~]# sed -r 's#(^[^0-9]*)([0-9]*)([^a-zA-Z].*[^a-zA-Z])([a-zA-Z]*$)#\1\4\3\2#g' /etc/passwd
root:x:bash:0:root:/root:/bin/0
bin:x:nologin:1:bin:/bin:/sbin/1
......
sa:x:bash:807::/home/sa:/bin/889
sb:x:bash:808::/home/sb:/bin/890
sc:x:bash:809::/home/sc:/bin/891
[root@oldboy ~]#


    启发

    在学习使用正则表达式的时候,分析要求,选好分隔行信息的关键点,以此完成匹配。

本文出自 “Passionie” 博客,转载请与作者联系!

你可能感兴趣的:(linux,正则表达式)