Linux Shell 脚本编程(5)—文本过滤(正则表达式)

Linux Shell 脚本编程(5)—文本过滤(正则表达式)

文本过滤

正则表达式


  • 概念:一种用来描述文本模式的特殊语法
    由普通字符(例如:字符a到z),以及特殊字符(元字符,如/ * ?等)组成匹配的字符串
  • 文本过滤工具在某种模式之下,都支持正则表达式。
  • 注意!!!正则表达式,是以字符进行匹配的!!!!

1. 基本元字符集及其含义

元字符含义
^只匹配行首
$只匹配行尾
*单字符后紧跟*,匹配0个或多个此单字符
[ ]匹配[ ]内字符。可以是一个单字符,也可以是字符序列。可以使用.表示[ ]内字符序列范围,如用[1-5]代替[12345]
\用来屏蔽一个元字符的特殊含义。因为有时在shell中一些元字符有特殊含义。\可以使其失去应有意义
.匹配任意单字符
pattern{n}用来匹配前面pattern出现次数。n为次数
pattern{n, }m含义同上,但次数至少为n
pattern{n,m}含义同上,但pattern出现次数在n和m之间

这里写图片描述

#---grep命令使用---
jianliu@ubuntu:~/aa$ ls -l *.c
lrwxrwxrwx 1 jianliu jianliu  3 Oct  7 20:07 2.c -> 1.c
-rw-rw-r-- 1 jianliu jianliu 79 Oct  3 05:05 a1.c
-rw-rw-r-- 1 jianliu jianliu 79 Oct  3 05:17 b1.c
lrwxrwxrwx 1 jianliu jianliu  4 Oct  7 20:07 b3.c -> b1.c
lrwxrwxrwx 1 jianliu jianliu  4 Oct  7 20:07 b4.c -> b1.c
-rw-rw-r-- 1 jianliu jianliu 94 Oct  4 04:20 hello.c

jianliu@ubuntu:~/aa$ ls -l ?.c
lrwxrwxrwx 1 jianliu jianliu 3 Oct  7 20:07 2.c -> 1.c

#匹配权限位 \-:普通文件; r:所有者具有读权限。
#\-:‘-’特殊字符,进行转义!!!!
jianliu@ubuntu:~/aa$ ls -l | grep "\-r........"
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:05 a1.c
-rwxrwxr-x 1 jianliu jianliu 8501 Oct  6 19:26 app2
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:17 b1.c
-rw-rw-r-- 1 jianliu jianliu    0 Oct  7 23:16 efile
-rwxrwxr-x 1 jianliu jianliu    0 Oct 10 05:26 exe.app
-rw-rw-r-- 1 jianliu jianliu   94 Oct  4 04:20 hello.c
-rwxrwxr-x 1 jianliu jianliu   58 Oct 10 05:51 names.txt
-rwxrwxr-x 1 jianliu jianliu    0 Oct 10 05:49 names.txt~
-rw------- 1 jianliu jianliu  225 Oct 10 05:33 nohup.out
-r--r--r-- 1 jianliu jianliu    0 Oct  7 20:25 rd_file
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell01.sh
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell02.sh
-rwxrwxr-x 1 jianliu jianliu  382 Oct 10 06:49 test.sh
-rwxrwxr-x 1 jianliu jianliu  337 Oct 10 06:48 test.sh~
-rw-rw-r-- 1 jianliu jianliu 4827 Oct  7 23:21 test.txt

jianliu@ubuntu:~/aa$ ls -l | grep 'shell0.'
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell01.sh
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell02.sh

2. 使用句点匹配单字符

  • 句点“.”可以匹配任意单字符。
    例如,如果要匹配一个字符串,以 beg开头,中间夹一个任意字符,那么可以表示为b e g . n, “.”可以匹配字符串头,也可以是中间任意字符。

在ls -l命令中,可以匹配一定权限:

#在ls-l命令中,可以匹配一定权限:
...x..x..x   (pattern)
此格式匹配用户本身,用户组及其他组成员的执行权限。
drwxrwxrw-    未匹配
-rw-rw-rw-    未匹配
-rwxrwxr-x    匹配
-rwx-r-xr-x   匹配

假定正在过滤一个文本文件,对于一个有10个字符的脚本集,要求前4个字符之后为xc,匹配操作如下
....xc....
1234xc9870  匹配
2432xx0977  不匹配
0023xa3456  不匹配
9932xc3421  匹配

#注意! “.”允许匹配ASCII集中任意字符、或者字母、或者数字。

3. 行首以^匹配字符串或字符序列

  • 只允许在一行的开始匹配字符或单词。例如,使用 ls -l命令,匹配目录。之所以可以样做是因为ls -l命令结果每行第一个字符是d,即代表一个目录。
^d
drwxrwxrw-    匹配
-rwxrw--wx    不匹配
drw-r-xr--     匹配

^001
1234cx2345   不匹配
2353xx9011   不匹配
0011xa8345   匹配

jianliu@ubuntu:~/aa$ ls -l | grep ^d
drwxrwxr-x 3 jianliu jianliu 4096 Oct  3 06:44 bb

jianliu@ubuntu:~/aa$ ls -l | grep ^.rw.rw.r..
lrwxrwxrwx 1 jianliu jianliu    3 Oct  7 20:07 2.c -> 1.c
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:05 a1.c
-rwxrwxr-x 1 jianliu jianliu 8501 Oct  6 19:26 app2
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:17 b1.c
lrwxrwxrwx 1 jianliu jianliu    4 Oct  7 20:07 b3.c -> b1.c
lrwxrwxrwx 1 jianliu jianliu    4 Oct  7 20:07 b4.c -> b1.c
drwxrwxr-x 3 jianliu jianliu 4096 Oct  3 06:44 bb
-rw-rw-r-- 1 jianliu jianliu    0 Oct  7 23:16 efile
-rwxrwxr-x 1 jianliu jianliu    0 Oct 10 05:26 exe.app
-rw-rw-r-- 1 jianliu jianliu   94 Oct  4 04:20 hello.c
-rwxrwxr-x 1 jianliu jianliu   58 Oct 10 05:51 names.txt
-rwxrwxr-x 1 jianliu jianliu    0 Oct 10 05:49 names.txt~
-rwxrwxr-x 1 jianliu jianliu  382 Oct 10 06:49 test.sh
-rwxrwxr-x 1 jianliu jianliu  337 Oct 10 06:48 test.sh~
-rw-rw-r-- 1 jianliu jianliu 4827 Oct  7 23:21 test.txt

#将各种模式结合使用
^...4cx....
#结果为:
1234cx2345   匹配
2354cc9011   不匹配
4564cx8345   匹配

#查找shell01.sh中的注释
jianliu@ubuntu:~/aa$ grep ^# shell01.sh
#!/bin/bash
#echo $4
#echo $5

4. 行尾以$匹配字符串或字符

  • 可以说$^正相反,它在行尾匹配字符串或字符, $符号放在匹配单词后。假定要匹配以词trouble结尾的所有行,操作为:trouble$
jianliu@ubuntu:~/aa$ ls -l | grep c$
lrwxrwxrwx 1 jianliu jianliu    3 Oct  7 20:07 2.c -> 1.c
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:05 a1.c
-rw-rw-r-- 1 jianliu jianliu   79 Oct  3 05:17 b1.c
lrwxrwxrwx 1 jianliu jianliu    4 Oct  7 20:07 b3.c -> b1.c
lrwxrwxrwx 1 jianliu jianliu    4 Oct  7 20:07 b4.c -> b1.c
-rw-rw-r-- 1 jianliu jianliu   94 Oct  4 04:20 hello.c
    ^$   匹配空行
    ^.$  匹配包含一个字符的行

5. 用*$匹配单字符串或或其重复序列

匹配字符u一次或多次 
comter   
computer
compuuter
compuuuuter

6. 使用\屏蔽一个特殊字符的含义

  • 忽视该特殊字符的含义,仅认为其是一个普通字符。
#特殊字符如下:
 $ .  ' "  * [ ]   ^ | 0 \ + ?

假定要匹配包含字符"."的各行,而"."代表匹配任意单字符的特殊字符,因此需要屏蔽其含义。操作如下:
\.
上述模式不认为反斜杠后面的字符是特殊字符,而是一个普通字符,即句点。

假定要匹配包含^的各行,将反斜杠放在它前面就可以屏蔽其特殊含义。如下:  \^

如果要在正则表达式中匹配以".pas"结尾的所有文件,可做如下操作:
\*\.pas
即可屏蔽字符*的特殊含义。

7. 使用[ ] 匹配一个范围或集合

  • [A-Z] : A的左侧和Z的右侧不能有空格!!, -的左右均不能有空格!!!
  • [A-Za-z]: 用于匹配所有字母,其中Z和a中间不能有空格!!!
#1    假定要匹配任意一个数字,可以使用:
[0123456789]
jianliu@ubuntu:~/aa$ ls -l | grep shell[012][012]\.
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell01.sh
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell02.sh

#2   使用"-"简化匹配任意一个数字的操作
[0-9]  #匹配数字
jianliu@ubuntu:~/aa$ touch shell03.sh
jianliu@ubuntu:~/aa$ touch shell10.sh
jianliu@ubuntu:~/aa$ touch shell11.sh
jianliu@ubuntu:~/aa$ ls -l | grep shell[0-9][0-9]\.
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell01.sh
-rwxr-xr-x 1 jianliu jianliu  109 Oct  6 19:15 shell02.sh
-rw-rw-r-- 1 jianliu jianliu    0 Oct 11 07:59 shell03.sh
-rw-rw-r-- 1 jianliu jianliu    0 Oct 11 07:59 shell10.sh
-rw-rw-r-- 1 jianliu jianliu    0 Oct 11 07:59 shell11.sh

#3
[a-z] 任意小写字符    #正确写法
[ a-z ]   #错误!!   [a - z]  #错误

#4-------------------------------------------------------------
[A-Za-z]  从 A-Z、a-z的字母范围
[A-Z a-z]  #错误!!

#5-----------------------------------------------------------
[A-Za-z0-9] 匹配任意字母或数字
jianliu@ubuntu:~/aa$ cat test0.txt
a 
D 
e 
c 
f 
3 
1 
5 
7
jianliu@ubuntu:~/aa$ cat test0.txt | grep [A-Ca-c0-3]
a 
c 
3 
1 

#6------------------------------------------------
#在字符序列结合使用中,可以用 [ ]指出字符范围。假定要匹配一单词,以 s开头,中间有任意字母,以t结尾,那么操作如下:
s[a-zA-Z]t
jianliu@ubuntu:~/aa$ cat test0.txt
st
sat
sbt
s@t
s2t
saat
sbbt
sabt
saaat
sbbbt
sabct
jianliu@ubuntu:~/aa$ cat test0.txt | grep s[a-zA-Z]t
sat
sbt

jianliu@ubuntu:~/aa$ cat test0.txt | grep s[a-zA-Z]*t
st
sat
saat
sabt
saaat
sabct

#7--------------------------------------------------
  #匹配所有包含system后跟句点的所有单词,这里S可大写或小写。
jianliu@ubuntu:~/aa$ cat test0.txt 
system.h
system
System.h
asytem.h
jianliu@ubuntu:~/aa$ cat test0.txt | grep [S,s]ystem\.
system.h
System.h

8. ^位于[ ]中,即[^符号集]匹配除符号集以外的其他单字符

jianliu@ubuntu:~/aa$ cat test0.txt
st
sat
sbt
s@t
s%t
s*&t
s2t
s3t
saat
sbbt
s22t
s33t
s@@t
s%%t
sabt
saaat
sbbbt
sabct

jianliu@ubuntu:~/aa$ cat test0.txt | grep s[^a-zA-Z0-9]*t
st
s@t
s%t
s*&t
s@@t
s%%t


  • 使用\{ \}匹配模式设置模式出现的次数

  • pattern\{n\} 匹配模式出现n次。
  • pattern\{n,\} 匹配模式出现最少n次。
  • pattern\{n,m\} 匹配模式出现n到m次之间,n , m为0 - 2 5 5中任意整数。

jianliu@ubuntu:~/aa$ cat test0.txt
st
sat
saat
saaat
sbt
sbbt
sbbbt
s2t
s22t
s222t
s@@t
s%%t
sabt
sabct

jianliu@ubuntu:~/aa$ cat test0.txt | grep 'sa\{2\}t'
saat

jianliu@ubuntu:~/aa$ cat test0.txt | grep 'sa\{2,\}t'
saat
saaat

jianliu@ubuntu:~/aa$ cat test0.txt | grep 'sa\{1,3\}t'
sat
saat
saaat

jianliu@ubuntu:~/aa$ cat test0.txt | grep 's[a-z]\{1,3\}t'
sat
saat
saaat
sbt
sbbt
sbbbt
sabt
sabct

jianliu@ubuntu:~/aa$ cat test0.txt | grep 's[a-z0-9]\{1,3\}t'
sat
saat
saaat
sbt
sbbt
sbbbt
s2t
s22t
s222t
sabt
sabct


#注意!!!
   cat test0.txt | grep sa\{2\}t   //写法错误!!,不能省去' '

9. 匹配子串( )

jianliu@ubuntu:~$ echo -e  "mabc\n mc\n mac" | grep -E 'm(ab)?c'
mabc
 mc

jianliu@ubuntu:~$ echo -e  "mabc\n mc\n mac" | grep 'm\(ab\)\?c'
mabc
 mc

##注意两种写法的区别,详细见下一篇博客【grep】

10. 匹配给定文本中所有的单词

```C++
( ?[a-zA-Z]+ ?)     
#“?”用于匹配单词前后可能出现的空格。 [a-zA-Z]+代表一个或多个字母(a~z和A~Z)。
//?前有一个空格!!!
```

11. 匹配一个IP地址

192.168.12.2
127.123.1.5
192.168.1.
....
192.168.1

jianliu@ubuntu:~/aa$ cat test0.txt | grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
192.168.12.2
127.123.1.5

jianliu@ubuntu:~/aa$ cat test0.txt | grep '[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}'
192.168.12.2
127.123.1.5

12. 匹配邮箱

jianliu@ubuntu:~/aa$ cat test0.txt
jianliu0627@qq.com
dfhao@163.com
1122333@foxmail.com
_hha23@qq.com
+hhaa12@qq.com
jianliu98qqcom
joann@163com
__123qq@163com

jianliu@ubuntu:~/aa$ cat test0.txt | grep '[a-zA-Z0-9_]\{1,\}@[a-z0-9]\{1,3\}\.[a-z]\{1,\}'
jianliu0627@qq.com
dfhao@163.com
_hha23@qql.com

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值