Regular Expression , RE, 是透过一些字符的排列,用以搜索/取代/删除 一列或多列文字字符串,是一个字符串处理的标准依据。如果你想要以正则表示法的方式处理字符串,就的要使用支持正则表示法的工具才行。
正则表达式是指在支持表达式的工具的情况下 ( 例如 vi , grep ) , 对字符串进行的搜索, 删除, 替换等等
正则表示发就是处理字符串的方法, 它是以行为单位来进行字符串处理的行为, 正则表示法透过一些特殊符号的辅助, 可以让使用者轻易的达到 搜索/删除/取代 某特定字符串的处理程序.
正则表达式基本上是一种表示法, 只要工具程序支持这种表示法, 那么该工具程序就可以作为正则表示法的字符串处理之用。 如 vi , grep ,awk , sed 等等.
作用: 因为每天系统产生的数据量很多, 没办法浏览所有的数据而查看想要的内容,所以就需要使用正则表式法,把有用的信息直接摘出来。
正则表示法与通配符是完全不一样的东西。通配符代表的是bash操作接口的一个功能,但正规表示法则一种字符串处理的表示方式,这两者要分的清楚。学习本章要将以前的通配符忘掉。
分为基础的正则表示法,和延伸的正则表示法 两种。
使用 grep 锻炼 正则表示法
grep -n 'the' grep.txt ( 显示行号 , 查看 grep.txt中的含有 the的字符 )
grep -vn 'the' grep.txt ( 反向选择 )
grep -in 'the' grep.txt ( 不区分大小写, 显示有 'the' 内容的数据 )
如果我要搜索 test , taste时, 我们发现其实他们有个共同特点 t ? st , 这样的话。我们就可以 grep -n 't[ae]st' , 其中[ ]的含义是其中任何一个字符
grep -n '[^g]oo' grep.txt ( 这样, 只要是出现oo, 并且前面不出现g的都搜索出来 )
grep -n '[^a-z]oo' grep.txt ( 这样, oo前面所有的不是小写的,搜索出来) 但是考虑到语系环境问题, 可能 a-z 并不是连续的, 因为有时候是 Aa Bb Cc 这样子排列的,这时我们可以使用[:lower:]表示小写
[:alnum:] 代表所有大小写字母和数字
[:alpha:] 代表所有大小写字母
[:blank:] 代表空格与 tab 键
[:cntrl:] 代表键盘上的控制按键
[:digit:] 代表数字按键
[:graph:] 除了空格(包括tab)的其他字符
[:lower:]小写字母
[:print:] 任何可以被打印的字符
[:punct:] 代表标点符号
[:upper:]代表大写字母
[:space:]空格
[:xdigit:] 16进制数
将所有的带数字的都搜索出来 : grep -n '[[:digit:]]' grep.txt
行首与行尾字符 : ^(行首) $(行尾) grep -n '^the' grep.txt ( 搜索以 the 开头的行 )
grep -n '[a-z]$' grep.txt ( 行尾是小写字母的行 )
例子:
vi
1 "Open Source" is a good mechanism to develop programs.
2 apple is my favorite food.
3 Football game is not use feet only.
4 this dress doesn't fit me.
5 However, this dress is about $ 3183 dollars. ^M
6 GNU is free air not free beer. ^M
7 Her hair is very beauty. ^M
8 I can't finish the test. ^M
9 Oh! The soup taste good. ^M
10 motorcycle is cheap than car.
11 This window is clear.
12 the symbol '*' is represented as start.
13 Oh! My god!
14 The god software is a library for drafting programs. ^M
15 You are the best is mean you are the no.1.
16 The world<Happy>is the same with "glad".
17 i like dog.
18 google is the best tools for search keyword.
19 goooooogle yes!
20 go! go! Let's go.
21 #I am VBird
22
grep -n 'the' regular_express.txt 查找有 'the'的行
grep -vn 'the' regular_express.txt 查找没有'the'的行,反向查找
grep -in 'the' regular_express.txt 查找'the' 不区分大小写
grep -n 't[ae]st' regular_express.txt 查找有 test 和 tast 这两个字符
grep -n 'oo' regular_express.txt 查找有 'oo'的
grep -n '[^g]oo' regular_express.txt 查找带'oo'的并且前边不是g
grep -n '[^a-z]oo' regular_express.txt txt 查找带'oo'的并且前边不是小写字母
grep -n [0-9] regular_express.txt 查找带数字的行 = grep -n '[^[:lower:]]oo' regular_express.txt
grep -n '^[^[:alpha:]]' regular_express.txt
^ 这个符号,在【】里边和外边是不一样的,在里边表示反向,在外边表示行首的意思。
$ 行末的意思, grep -n '\.$' regular_express.txt , 因为. 小数点是特殊字符,所以要转义,该句的意思是,查出以小数点结尾的行
grep -n '^$' regular_express.txt 查找出空白行
正则表达式下 . 小数点代表 一定有一个任意字符
正则表达式下 * 星号 代表重复前一个 0 到无穷多次
. * 点和星的用法
.相当于站位符号, 一个点代表一个字符, grep -n 'g..d' grep.txt ( 则带 good的单词会被搜索出来, 但同时 god 就不会被搜索出来)
o* 因为 * 代表 0~ 无穷,当时0的时候,所以以上内容就可以理解为拥有空字符或一个o以上的字符,特别注意,因为准许空字符(就是没有字符也可以),所以, grep -n 'o*' regular_express.txt 就会把所有的内容打印到屏幕上。如果是 oo* 则表示至少有一个o,第二个则可有可无,所以,凡是 o,oo,ooo,等等全部会被打印出来。
* [o*] 表示 星从 0 ~ 无限次的重复 o , 其中* 星前边的最贴近的 o 不具备实际意义, 所以会将文档数据全部搜索出来, 因为当 0 个O 时就表示没有给出条件,所以全部搜索出来,而如果是[oo*] 则表示要搜索出 o oo ooo oooo 这样,至少有一个o . 同理, 当我使用 'ooo*' , 最后一个o 可以不理, 所以至少要有2个oo
grep -n 'oo*' grep.txt ( 至少有1个 o 的行会被搜索出来)
{} 限定连续RE字符范围
grep -n 'go\{2,5\}g' grep.txt ( 其中 \ 为逃脱字符, 因为 { } 属于特殊字符, 需要逃脱使用 )
限定2个 grep -n 'o\{2\}' regular_express.txt
限定2-5个 grep -n 'o\{2,5\}' regular_express.txt
限定2个以上 grep -n 'o\{2,\} regular_express.txt
sed工具
sed本身也是一个管线命令,可以分析 standard input, 还可以将数据进行取代,删除,新增,截取特定行
sed [-nefr] [动作]
-n : 使用安静(silent)模式,在一般 sed 的用法中,所有来自 stdin的数据一般都会被列出在屏幕上,但是如果加上 -n 参数后,则只有经过 sed 特殊处理的那一行(或者动作)才会被列出来。
-e : 直接在指令列模式上进行 sed 的动作编辑
-f : 直接将 sed 的动作卸载一个档案内, -f filename
-r : sed 动作支持延伸正则表达式
n1,n2 function : n1,n2 不见得会存在,一般代表 选择进行动作的行数。例如 如果我的动作是需要在 10到 20之间进行的,则10,20 动作行为
function 包含以下内容
a : 新增,新增的内容会在目前的下一行出现
c : 取代, c 后面可以接字符串,这些字符串可以取代 n1,n2之间的行
d: 删除 ,
i : 插入m i后面可以接字符串,会出现在目前行的上一行
p : 打印
s : 取代,一般形式为 1,20s/old/new/g 似成相识,因为跟学习 vi时一样
nl /etc/passwd | sed '2,5d' 删除2-5 行
set '2a drink tea' 增加新行
nl /etc/passwd | sde '2,5c No 2-5 number' 替换
nl /etc/passwd | sed -n '5,7p' 打印5-7行,安静模式
延伸的正则表达式
有些工具不支持,所以目前只要了解基础的正则表达式就可以了
printf '打印格式' 实际内容
有点类似C语言中的 printf函数
awk 工具
awk则比较倾向于下一行当中分成数个字段 因此awk相当适合小型数据处理, 类似 awk '条件类型1{动作1} 条件类型2{动作2}...' filename
last -n 5 | awk '{print $1 "\t" $3}' 该语句的含义是,打印 1-3 栏,并且第一栏使用 制表符
diff
对比档案
diff [-bBi] from -file to -file
-b : 忽略一行当中,仅有多个空白的差异 例如 about me , about me
-B : 忽略空白行的差异
-i : 忽略大小写的不同
diff passwd.old passwd.new
patch
前面比较出差异,diff,如何升级,就是用 patch , 一般使用 diff知错出来的比较档案使用的扩展名为 .patch
patch -pN < patch_file
-p : 取消几层目录,接数字
-R : 还原,将新的文件还原成原来的旧文件
patch -p0 < passwd.patch
patch -R -p0 < passwd.patch 还原成旧文件