三剑客之grep 正则表达式 扩展正则 posix字符集


本篇内容

  • 1、正则表达式
    • 普通正则
    • 符号
  • 2、扩展正则表达式
    • 符号
  • 3、grep命令
  • 4、Posix字符集(了解)

grep命令


grep介绍

# grep命令主要用于过滤文本,grep家族如下
grep: 在文件中全局查找指定的正则表达式,并打印所有包含该表达式的行
egrep:扩展的egrep,支持更多的正则表达式元字符
fgrep:固定grep(fixed grep),有时也被称作快速(fast grep),它按字面解释所有的字符
# grep命令格式如下
grep [选项] PATTERN 文件1 文件2 ...

[root@egon ~]# grep 'root' /etc/passwd
[root@egon ~]# fgrep 'bash' /etc/passwd

找到: grep返回的退出状态为0
没找到:    grep返回的退出状态为1
找不到指定文件:    grep返回的退出状态为2

grep 命令的输入可以来自标准输入或管道,而不仅仅是文件,例如:
ps aux |grep 'nginx'


选项参数

# 匹配搜索到的文本内容后显示该行内容
grep 选项 '正则表达式' 文件路径
-n 匹配时显示行号
-o 只显示匹配成功的内容
-q 静默输出,用于判断结果成功与否

-A 匹配成功行以及他的后n行 -A3 (后3行)
-B 匹配成功行以及他的前n行 -B3 (前3行)
-C 匹配成功行以及他的前后n行 -C3 (前后3行)

-w 过滤单词(左右必须是空格或特殊符号)
-c 匹配成功几行
-r 递归
-l 如果匹配成功,则只将文件名打印出来,失败则不打印.
通常-rl一起用,grep -rl 'root' /etc

-E 启用扩展正则表达式
-P 使用非贪婪匹配 (使用?符号把贪婪变成非贪婪)

示例

例:
#vim中匹配使用正则
egon111egon111
Egon234
...
:% s/egon/xxx/   #每行只匹配找到的第一个
:% s/egon/xxx/g  #匹配所有
:% s/egon/xxx/gi #匹配忽略大小写
:% s/[Ee]gon/xxx/g #[]表示匹配其中任一字符

正则表达式


正则表达式介绍

正则表达式,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。正则表达式由元字符组成,通常被用来检索、替换那些符合某个模式(规则)的文本(许多程序设计语言都支持利用正则表达式进行字符串操作)。

元字符:是一类可以表达出超越其字面本身含义的特殊字符

shell元字符(也称为通配符): 由shell解释器来解析,如rm -rf *.pdf,元字符*Shell将其解析为任意多个字符
正则表达式元字符: 由各种执行模式匹配操作的程序来解析,比如vi、grep、sed、awk

例如:vim示例:
:1,s/tom/EGON/g    # 如anatomy、tomatoes及tomorrow中的“tom”被替换了,而Tom确没被替换
:1, s/\<[Tt]om\>/EGON/g

基本正则元字符集

元字符         功能                                        示例    
^             行首                                        ^love
行尾                                         love
.             除了换行符以外的任意单个字符                     l..e
*             前导字符的零个或多个                            ab*love
.*            所有字符                                      a.*love
[]            字符组内的任一字符                              [lL]ove
[^]           对字符组内的每个字符取反(不匹配字符组内的每个字符)   [^a-z0-9]ove
^[^]          非字符组内的字符开头的行

[a-z]         小写字母
[A-Z]         大写字母
[a-Z]         小写和大写字母
[0-9]         数字

\            用来转义元字符                                      love\.    
\<           词首定位符 单词一般以空格或特殊字符做分隔、连续的字符组成  \<love
\>           词尾定位符                                         love\>
\(..\)        匹配稍后将要使用的字符的标签                    \(love\)able\1er    
                                                         :1,$ s/\(192.168.11\).66/\1.50/g

x\{m\}          字符x重复出现m次                                e\{3\}
x\{m,\}         字符x重复出现m次以上                             e\{3,\}                     
x\{m,n\}        字符x重复出现m到n次                             e\{3,6\}    

符号 ^ $ . * ?

#-------------------------#
^ 以什么开头
$ 以什么结尾
. 任意一个字符(换行符除外)
* 左侧那个字符出现0次或无穷次,贪婪匹配(不能单独使用)
.* 匹配没有或所有,贪婪匹配(匹配最多字符的情况)
.*? 非贪婪匹配(grep中需配 -P 参数)
#-------------------------#
# 示例1
[root@egon day08]# cat c.txt 
a
ab
abb
abbbabb
bbbbb
bbabb1bb
bba1bbbb
123abbbbbb
444aaaa
[root@egon day08]# grep -n 'ab*' c.txt 
1:a
2:ab
3:abb
4:abbbabb
6:bbabb1bb
7:bba1bbbb
8:123abbbbbb
9:444aaaa
[root@egon day08]# grep -o 'ab*' c.txt 
a
ab
abb
abbb
abb
abb
a
abbbbbb
a
a
a
a
[root@egon day08]# 


.* 匹配没有或者无穷个任意字符
[root@egon day08]# cat d.txt 
a1b
a123b456b33333333
a++b
ab
a1231231212312123123b
a123123213
[root@egon day08]# grep 'a.*b' d.txt
a1b
a123b456b33333333
a++b
ab
a1231231212312123123b
[root@egon day08]# 

## 非贪婪匹配 需要 grep -P 参数
.*? 非贪婪匹配
[root@egon day08]# cat e.txt 
<a href="http://www.baidu.com">"我他吗的是百度啊"</a>
<a href="http://www.sina.com.cn">"我他吗的是新浪啊"</a>
[root@egon day08]# grep 'href=".*"' e.txt 
<a href="http://www.baidu.com">"我他吗的是百度啊"</a>
<a href="http://www.sina.com.cn">"我他吗的是新浪啊"</a>
[root@egon day08]# 
[root@egon day08]# grep -P 'href=".*?"' e.txt 
<a href="http://www.baidu.com">"我他吗的是百度啊"</a>
<a href="http://www.sina.com.cn">"我他吗的是新浪啊"</a>
[root@egon day08]# grep -Po 'href=".*?"' e.txt 
href="http://www.baidu.com"
href="http://www.sina.com.cn"
[root@egon day08]# grep -Po 'href=".*?"' e.txt | cut -d= -f2
"http://www.baidu.com"
"http://www.sina.com.cn"


符号 [ ]

#==========================
[] 匹配括号内任意一个字符
[a-z] 匹配一个小写字母
[A-Z] 匹配一个大写字母
[a-zA-Z] 匹配一个大小写字母
[0-9] 匹配一个数字
[^] 取反
# 注意 :
[+*/-] -必须放在两端(匹配+-*/)
#==========================

#=======================示例
[root@egon day08]# cat f.txt 
a1c
aAc
a11c
aac
aaaaaaaaaaaaaaaaaaaaa0cccccc
[root@egon day08]# grep 'a[0-9]c' f.txt
a1c
aaaaaaaaaaaaaaaaaaaaa0cccccc
[root@egon day08]# 
[root@egon day08]# grep 'a[0-9][0-9]c' f.txt
a11c
[root@egon day08]# grep 'a[A-Z]c' f.txt
aAc
[root@egon day08]# 
[root@egon day08]# grep 'a.c' f.txt 
a1c
aAc
aac
aaaaaaaaaaaaaaaaaaaaa0cccccc
a+c
a-c
a*c
a/c
[root@egon day08]# grep 'a[+-*/]c' f.txt 
grep: Invalid range end
[root@egon day08]# grep 'a[+*/-]c' f.txt 
a+c
a-c
a*c
a/c
[root@egon day08]# cat f.txt 
a1c
aAc
a11c
aac
aaaaaaaaaaaaaaaaaaaaa0cccccc
a+c
a-c
a*c
a/c
axxc
[root@egon day08]# grep 'a[^0-9]c' f.txt 
aAc
aac
a+c
a-c
a*c
a/c
[root@egon day08]# grep 'a[^0-9][^0-9]c' f.txt 
axxc



扩展正则表达式

# 若想使用扩展正则

grep加-E 或 egrep 或转义\

sed 加 -r 参数 或转义

AWK 直接支持大多数扩展正则,更多支持需要加选项--posix选项

扩展正则元字符集

# 扩展正则元字符
+                   匹配一个或多个前导字符        [a-z]+ove    
?                   匹配零个或一个前导字符        lo?ve    
a|b                 匹配a或b                   love|hate
()                  组字符                     love(able|rs)  (egon)+
(..)(..)\1\2        标签匹配字符                (love)able\1er
x{n}                x出现n次                   e{3}        
x{n,}               x出现n次至无穷次             e{3,}
x{n,m}              x出现n次至m次               e{3,6}


边界与 () 的应用

# 界定单词的边界
[root@egon day08]# grep 'root' g.txt 
root123
root 123
aaaaroot
[root@egon day08]# grep -w 'root' g.txt 
root 123
[root@egon day08]# grep  '\<root\>' g.txt 
root 123
[root@egon day08]# grep  '\broot\b' g.txt 
root 123
[root@egon day08]# grep  '\(root\)' g.txt 

# 把重复内容分组 ( ) 
例如:
abchabcfabck
可以用\(abc\)h\1f\2k 表示

[root@zabbix ~]# cat 1.txt
asdfsdfdsfdsfaf
455
abc1abc2abc4
[root@zabbix ~]# grep '\(abc\)1\12\14' 1.txt 
abc1abc2abc4

[root@egon day08]# cat h.txt 
mababababbbbbbbbbbbbbbbbbb
mab123
m
1111mabbbbbb
2222bbbbbba
[root@egon day08]# grep 'm\(ab\)*' h.txt 
mababababbbbbbbbbbbbbbbbbb
mab123
m
1111mabbbbbb
[root@egon day08]# vim k.txt
[root@egon day08]# cat k.txt 
loveablelover1111
loveable
lover
[root@egon day08]# vim k.txt 
[root@egon day08]# cat k.txt 
loveablelover1111
loveable1111
lover1111
[root@egon day08]# grep 'loveablelover' k.txt 
loveablelover1111
[root@egon day08]# grep '\(love\)able\1r' k.txt 
loveablelover1111
[root@egon day08]# 

{} 的应用

x\{n,m\} x出现n次到m次
x\{n,\} x出现n次到无穷次,x\{0,\}等同于x*
x\{n} x出现n次

[root@egon day08]# cat 1.txt 
a
ab
abb
abbb
abbbb
bbbbbb
[root@egon day08]# egrep 'ab{2}' 1.txt 
abb
abbb
abbbb
[root@egon day08]# egrep 'ab{0,}' 1.txt 
a
ab
abb
abbb
abbbb
[root@egon day08]# egrep 'ab*' 1.txt 
a
ab
abb
abbb
abbbb
[root@egon day08]# egrep 'ab{1,3}' 1.txt 
ab
abb
abbb
abbbb
[root@egon day08]# 


符号 + * ? | \ 的应用

* 左侧那个字符出现0或无穷次,相当于{0,}
+ 左侧那个字符出现1或无穷次,相当于{1,}
? 左侧那个字符出现0到1次,相当于{0,1}

grep -E 'company|companies' 2.txt
grep -E 'compan(y|ies)' 2.txt

#以上两者相同效果,但是第二种方式的效率更高

\t 制表符
\n 换行
\r 换行
[root@egon day08]# cat 4.sh 
Alex213sb
    Wpq2222b
    yH438PIG
    egon666
    egon
[root@egon day08]# grep -E '^[a-zA-Z]+[0-9]+[a-zA-Z]' 4.sh
[root@egon day08]# grep -E '^[a-zA-Z]+[0-9]+[a-zA-Z]+' 4.sh
Alex213sb
[root@egon day08]# grep -E '[a-zA-Z]+[0-9]+[a-zA-Z]+' 4.sh
Alex213sb
    Wpq2222b
    yH438PIG
[root@egon day08]#
# 有特殊情况\t \n \r等 
需要在正则表达式前加上 [root@egon day08]# egrep -v'^#|^[ \t]*$' /etc/ssh/sshd_config
显示结果去除了 井开头行,空行,有空格的行,有制表符的行

总结

grep:               使用基本元字符集    ^, $, ., *, [], [^], \< \>,\(\),\{\}
egrep(或grep -E):    使用扩展元字符集    ?, +, { }, |, ( )
# 注:grep也可以使用扩展集中的元字符,仅需要对这些元字符前置一个反斜线

\w  所有字母与数字,称为字符[a-zA-Z0-9]    'l[a-zA-Z0-9]*ve'            'l\w*ve'
\W  所有字母与数字之外的字符,称为非字符     'love[^a-zA-Z0-9]+'          'love\W+'
\b  词边界                             '\blove\b'                    '\<love\>'

posix定义的字符分类

# 表达式             功能                                        示例
[:alnum:]       字母与数字字符                             [[:alnum:]]+  
[:alpha:]       字母字符(包括大小写字母)                     [[:alpha:]]{4}
[:blank:]       空格与制表符                                [[:blank:]]*
[:digit:]           数字字母                                [[:digit:]]?
[:lower:]       小写字母                                    [[:lower:]]{5,}
[:upper:]       大写字母                                    [[:upper:]]+
[:punct:]       标点符号                                    [[:punct:]]
[:space:]       包括换行符,回车等在内的所有空白[[:space:]]+


# 详解
[:alnum:] Alphanumeric characters.
匹配范围为 [a-zA-Z0-9]
[:alpha:] Alphabetic characters.
匹配范围为 [a-zA-Z]
[:blank:] Space or tab characters.
匹配范围为 空格和TAB键
[:cntrl:] Control characters.
匹配控制键 例如 ^M 要按 ctrl+v 再按回车 才能输出
[:digit:] Numeric characters.
匹配所有数字 [0-9]
[:graph:] Characters that are both printable and visible. (A space is print-
able, but not visible, while an a is both.)
匹配所有可见字符 但不包含空格和TAB 就是你在文本文档中按键盘上能用眼睛观察到的所有符号
[:lower:] Lower-case alphabetic characters.
小写 [a-z]
[:print:] Printable characters (characters that are not control characters.)
匹配所有可见字符 包括空格和TAB
能打印到纸上的所有符号
[:punct:] Punctuation characters (characters that are not letter, digits, con-
trol characters, or space characters).
特殊输入符号 +-=)(*&^%$#@!~`|\"'{}[]:;?/>.<,
注意它不包含空格和TAB
这个集合不等于^[a-zA-Z0-9]
[:space:] Space characters (such as space, tab, and formfeed, to name a few).

[:upper:] Upper-case alphabetic characters.
大写 [A-Z]
[:xdigit:] Characters that are hexadecimal digits.
16进制数 [0-f]

# 使用方法:
[root@egon ~]# grep --color '[[:alnum:]]' /etc/passwd

练习

正则表达式及字符处理

目标文件/etc/passwd,使用grep命令或egrep
1.显示出所有含有root的行:
2.输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的内容:
3.  显示出有多少行含有nologin。
4.显示出那些行含有root,并将行号一块输出。
5.显示出文件中
6.新建用户
    abominable
    abominate
    anomie
    atomize
    编写正则表达式,将他们匹配出来
    egrep 'a.omi(nabl|nat|z|)e' /etc/passwd
7.建四个用户
    Alex213sb
    Wpq2222b
    yH438PIG
    egon666
    egon

    过滤出用户名组成是字母+数字+字母的行
[root@MiWiFi-R3-srv ~]# egrep '^[a-Z]+[0-9]+[a-Z]+' /etc/passwd
8.显示出/etc目录下所有包含root的文件名
9. 过滤掉/etc/ssh/sshd_config内所有注释和所有空行
grep -v '^#' /etc/ssh/sshd_config |grep -v '^ *$'
Copyright © 2009 - Now . XPBag.com . All rights Reserved.
夜心的小站 » 三剑客之grep 正则表达式 扩展正则 posix字符集

提供最优质的资源集合

立即查看 了解详情