首页 > 代码库 > 正则表达式与三剑客的使用技巧

正则表达式与三剑客的使用技巧



1.正则表达式的基础


^               ^锚定行的开始如:/^sed/匹配所有以sed开头的行

$               $锚定行的结束 如:/sed$/匹配所有以sed结尾的行

.                .匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d

?               代表前趋字符的一次出现

*               *匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行

[]              匹配指定范围内的任意单个字符,如/[Ss]ed/匹配sed和Sed

[^]             匹配指定范围外的任意单个字符

                 如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行

/<               锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行

/>               锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行

/( /)            引用标识,可以多次引用,并在后面以/1 /2来引用

x/{m,n/}     代表x的至少m次,至多n次出现

|                 用于使用多个正则条件,匹配之一即可

+                与. *类似,表示1个或多个重复字符

()               用于将多个内容组成单元组

\(..\)        保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers

&               保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**

x\{m\}        重复字符x,m次,如:/0\{5\}/匹配包含5个o的行

x\{m,\}       重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行

x\{m,n\}     重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行

2.grep

作用:文本搜索工具,根据用户指定的"模式(过滤条件)"对目标文本逐行进行匹配检查;打印匹配的行
模式:有正则表达式的元字符及文本字符所编写的过滤条件

正则表达式引擎
grep [OPTIONS] [PATTERN] [FILE...] 
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]


常用选项:

--color=auto           对匹配到的文本着色后高亮显示

-E                         使用正则扩展

-e pattern               使用pattern中的正则

-f  file                   使用文件中的正则

-i                          忽略大小写(性能较差,最好先用tr统一转换成大写或小写)

-o                         仅显示匹配到字符串本身;

-v                         反向显示不匹配的行

-V                        显示版本号


输出控制选项:

-n                         输出行号

-q                         不显示未匹配的内容

-r                         递归方式扫描文件

-l                         只输出匹配的文件名

-L                        只输出不匹配的文件名

-c                         只显示匹配的个数

-A                       匹配的到后面几行也显示出来
-B                       匹配的到前面几行也显示出来
-C                        上下文,匹配的到前后面几行也显示出来


匹配次数:用在要指定其出现的次数的字符的后面,用户限制其前面字符出现的次数

:                       匹配器前面的字符任意次:0,1,多次

                          例如:grep "xy",abxy aby xxxy yab

.*                        匹配任意长度的任意字符,贪婪模式,能匹配多长就匹配多长
\?                       匹配其前面的字符0次或者1次;即其前面的字符可有可无的
+                       匹配其前面的字符一次或多次;即其前面的字符出现至少1次
{m}                    匹配其前面的字符m次
{m,n}                 匹配其前面的字符至少m次,至多n次
{0,n}                  至多n次

{m,}                   至少m次


位置锚定:

^                        行首锚定;用于模式的最左侧
$                        行尾锚定;用于模式的最右侧
^PATTERN$       用PATTERN来匹配整行
^$                      空白行
^[[:space:]]*$      空行或包含空白字符的行


单词:              非特殊字符组成的连续字符(字符串)都为单词
\< 或 \b              词首锚定,用于单词模式的左侧,例如:grep "\<word"
> 或 \b               词尾锚定,用于单词模式的右侧,例如:grep "word>"
\<PATTERN>     匹配完整单词

分组及引用:
()                       将一个或多个字符捆绑在一起,当作一个整体进行处理,例如:(xy)*ab
Note                   分组括号中的模式匹配到的内容会被正则表达式引擎自动记录到内部的变量中,这些变量为:
                   \1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符
                   \2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符
                   \3:后向引用,引用前面的分组括号中的模式所匹配到的字符


常用示例:

1、显示/etc/passwd文件中不以/bin/bash结尾的行
     grep -v "/bin/bash$" /etc/passwd


2、找出/etc/passwd文件中的两位数或三位数
     grep "\<[[:digit:]]{2,3}>" /etc/passwd


3、找出/etc/rc.d/rc.sysinit或/etc/grub2.cfg文件中,以至少一个空白字符开头,且后面非空白字符的行
     grep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg


4、找出"netstat -tan"命令的结果中以"LISTEN"后跟0、1或多个空白字符结尾的行
     netstat -tan|grep "LISTEN[[:space:]]*$"


5、grep "(l..e).*\1" lovers.txt

     He loves his lover.
     He likes his lover.
     She likes her liker.
     She loves her liker.

6、grep -i ‘root‘ /etc/passwd                              不区分大小写显示文件中有root的行

7、grep -v ‘^root‘  /etc/passwd                          显示文件中开关不是root和行

8、grep -n ‘root‘  /etc/passwd                            显示文件中含有root的行,且打印此行在文件中的行号

9、grep -lr ‘$root‘  /etc                                     递归查找/etc下包含行结尾为root的文件名

10、grep -Lr ‘root‘  /etc                                    递归查找/etc下文件中不包含root的文件名

11、grep -c ‘root‘  /etc/passwd                           统计文件中root出现的行数

12、grep "hello | world"  1.cpp                         匹配包含hello的行和world的行


         egrep命令:支持扩展正则表达式实现类似于grep文本过滤功能:grep -E
正则表达式引擎egrep [OPTINS] PATTERN [FILE]
                  选项:与grep选项相似
                -G:支持基本正则表达式

扩展正则表达式的元字符:
字符匹配:
.              匹配任意单个字符
[]             匹配指定范围内的任意单个字符
[^]           匹配指定范围外的任意单个字符


次数匹配:
           匹配器前面的字符任意次:0,1,多次

.:           匹配任意长度的任意字符,贪婪模式,能匹配多长就匹配多长
?              匹配其前面的字符0次或者1次;即其前面的字符可有可无的
+             匹配其前面的字符一次或多次;即其前面的字符出现至少1次
{m}         匹配其前面的字符m次
{m,n}      匹配其前面的字符至少m次,至多n次
{0,n}       至多n次
{m,}        至少m次

位置锚定:
^             行首锚定;用于模式的最左侧
$             行尾锚定;用于模式的最右侧
\<或\b      词首锚定,用于单词模式的锚定
>或\b       词尾锚定,用于单词模式的锚定


分组及引用:
()                    分组;括号内模式匹配到的字符会被记录到正则表达式引擎的内部变量中


后向引用:\1,\2....或:
a|b                  a或b
C|cat               C或cat
(c|C)at            cat或Cat


常用示例:


1、找出/proc/meminfo文件中,所有以大写或小写S开头的行;至少有三种实现方式
     grep "^[sS]" /proc/meminfo 
     grep -i "^sS" /proc/meminfo 
     grep -E "^(s|S)" /proc/meminfo 
     grep -E "^s|^S" /proc/meminfo

2、显示当前系统上root、centos或者user1用户的相关信息
    grep -E "^(root|centos|user1>)" /etc/passwd


3、找出/etc/rc.d/init.d/functions文件中某单词后跟一个小括号的行
    grep -Eo ‘_[[:alnum:]]+()‘ /etc/rc.d/init.d/functions 


4、使用echo命令输出一绝对路径,使用egrep取出基名
     echo "/root/ssf/erou/dfjl" | egrep -o "\<[[:alpha:]]>$" echo "/root/ssf/erou/dfjl" | grep -Eo "[^/]+/?$"


5、找出ifconfig命令结果中的1-255之间的数值
     ifconfig | grep -oE "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])>"


6、添加用户bash, testbash, basher以及nologin(其shell为/sbin/nologin)

     而后找出/etc/passwd文件中用户名同shell名的行
    grep -E "^([^:]+>).
\1$" /etc/passwd


3.sed

sed命令行格式为:sed [-nefri]  ‘command’  输入文本/文件        

常用选项:

-f               指定过滤脚本文件名

-e               后跟匹配表达式

-n               不显示默认输出

-r                sed 的动作支援的是延伸型正则表达式的语法
-i                直接修改读取的文件内容,而不是由屏幕输出
      
             

常用命令:

a ∶ 新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c ∶ 取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d ∶ 删除,因为是删除,所以 d 后面通常不接任何内容
 i ∶ 插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
 p∶ 列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起用
 s∶ 取代,可以直接进行替换的工作。通常这个 s 的动作可以搭配正则表达式。例如 1,20s/old/new/g

sed脚本上的命令:

sed ‘/root/a/text‘   /etc/passwd                              在文件的root那一行后增加新行text

sed ‘/root/c/text‘    /etc/passwd                             在文件的root那一行替换为text

sed ‘/root/i/text‘     /etc/passwd                            在匹配行前插入text

sed ‘/root/d‘           /etc/passwd                            删除文件中含有root的那一行

h/H                                                                  复制或附加模式缓冲区到一个buffer

g/G                                                                  从buffer中取出并复制或附加到当前模式缓冲区

sed -e ‘/root/{h;d;}‘ -e ‘$g‘ /etc/passwd                 将root行放在最后一行

p                                                                     打印行

sed -n ‘/root/{n;p;}‘ /etc/passwd                          打印root行的下一行

sed ‘1,3y/abcdef/ABCDEF/‘   /etc/passwd            映射1-3行的小写为大写

s/xxx/yyy/g                                                      文本替换


sed定址:

sed -n ‘1,3p‘ /etc/passwd                                    打印文件1-3行

sed -n  ‘/root/,/sshd/p‘  /etc/passwd                      打印文件root行与sshd行之间的行

sed -n ‘5,/^northeast/p‘  file


实例分享:

技术分享

技术分享

技术分享

技术分享

技术分享

技术分享


1、复制/etc/inittab文件至/tmp/目录,替换/tmp/inittab文件中的"id:3:initdefault"一行数字为5

# cp /etc/inittab /tmp/# sed‘s/id:3:initdefault/id:5:initdefault/‘ /tmp/inittab

2、复制/etc/rc.d/init.d/functions文件至/tmp目录,删除/tmp/functions文件的空白行

# cp /etc/rc.d/init.d/functions/tmp/# sed ‘/^[[:space:]]*$/d‘/tmp/functions

3、复制/boot/grub/grub.conf文件至/tmp/目录,删除/tmp/grub.conf文件中行首的空白字符

# cp /boot/grub/grub.conf /tmp/# sed ‘s@^[[:space:]]\+@@‘/tmp/grub.conf

4echo一个路径给sed,通过sed取出其路径名

例如echo"etc/sysconfig/network-scripts/" | sed,返回路径名/etc/sysconfig/

# echo"/etc/sysconfig/network-scripts/" | sed ‘s@[^/]\+/\?$@@‘


4.awk

awk命令主要用于文本内容的分析处理

如果对处理的数据需要生成报告之类的信息,或者处理的数据是按列进行处理的,最好使用awk

awk读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域

$0则表示所有域,$1表示第一个域,$n表示第n个域


awk是一个报告生成工具,旨在把文件中读取到的每一行的每个字段分别进行格式化

而后进行显示,awk支持使用变量、条件判断、循环、数组


比如说,以”:”分隔filename文本的每一行并且打印第一列

awk -F ‘:‘ ‘{print $1}‘ filename

通用格式:gawk ‘pattern {action}‘  file

                  cmd | gawk ‘pattern {action}‘

工作原理:awk 扫描一行,放入变量$0中,然后行被分隔成各个域

以指定的分隔符进行分离,默认为空格,可以通过参数FS指定。各个域都存于变量$i中,至多100个域

   sed和awk定制化显示举例

这里,我们可以制作一个文本my.txt,内容为:

This is my cat, my cat‘s name is betty
This is my dog, my dog‘s name is frank
This is my fish, my fish‘s name is george
This is my goat, my goat‘s name is adam

需要显示的结果为:

cat:betty
dog:frank
fish:george
goat:adam    

如果采用sed,可以输入

sed ‘s/This is my \(.*\),.*is \(.*\)/\1:\2/g‘ my.txt

技术分享

如果采用awk,则有两种方法

awk -F ‘[ ,]‘ ‘{print $4,$10}‘ OFS=":" my.txt 
awk -F ‘[ ,]‘ ‘{printf("%s:%s\n",$4,$10)}‘ my.txt

技术分享


1.显示GID小于500的组
   awk -F : ‘$3<500{print $1}‘ /etc/group


2.显示默认的shell为nologin的用户
   awk -F : ‘$7~/nologin$/{print $1}‘ /etc/passwd


3.显示eth0网卡文件的配置信息,注意,只显示等号后面的值
   awk -F = ‘{print $2}‘ /etc/sysconfig/network-scripts/ifcfg-eth0


4.显示/etc/sysctl。conf文件中定义的内核参数:只显示名称
   awk -F =‘ !/^#|^$/{print $1}‘/etc/sysctl.conf


5.显示eth0网卡的ip地址,通过ifconfig命令结果进行过滤
   ifconfig eth0 |awk ‘/inet addr/{print $2}‘ |awk -F : ‘{print $2}‘


正则表达式与三剑客的使用技巧