The answer is mysql> select ' s5testettestestes12' regexp ' *testettestestes[0-9][0-9]'; +-------------------------------------------------------------+ | ' s5testettestestes12' regexp ' *testettestestes[0-9][0-9]' | +-------------------------------------------------------------+ | 1 | +-------------------------------------------------------------+ 1 row in set (0.00 sec)mysql replace用法1.replace into replace into table (id,name) values('1','aa'),('2','bb') 此语句的作用是向表table中插入两条记录。如果主键id为1或2不存在 就相当于 insert into table (id,name) values('1','aa'),('2','bb') 如果存在相同的值则不会插入数据2.replace(object,search,replace) 把object中出现search的全部替换为replace select replace('www.163.com','w','Ww')--->WwWwWw.163.com 例:把表table中的name字段中的aa替换为bb update table set name=replace(name,'aa','bb') -------------------------------------------------------------------------------- 由MySQL提供的模式匹配的其它类型是使用扩展正则表达式。当你对这类模式进行匹配测试时,使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它们是同义词)。 扩展正则表达式的一些字符是: · ‘.’匹配任何单个的字符。 copyright Sqlclub · 字符类“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”、“b”或“c”。为了命名字符的范围,使用一个“-”。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。 · “ * ”匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的“x”字符,“[0-9]*”匹配任何数量的数字,而“.*”匹配任何数量的任何字符。 如果REGEXP模式与被测试值的任何地方匹配,模式就匹配(这不同于LIKE模式匹配,只有与整个值匹配,模式才匹配)。 为了定位一个模式以便它必须匹配被测试值的开始或结尾,在模式开始处使用“^”或在模式的结尾用“$”。 为了说明扩展正则表达式如何工作,下面使用REGEXP重写上面所示的LIKE查询: Sqlclub为了找出以“b”开头的名字,使用“^”匹配名字的开始: mysql> SELECT * FROM pet WHERE name REGEXP '^b'; +--------+--------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+------------+ | Buffy | Harold | dog | f | 1989-05-13 | NULL | | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | +--------+--------+---------+------+------------+------------+ 如果你想强制使REGEXP比较区分大小写,使用BINARY关键字使其中一个字符串变为二进制字符串。该查询只匹配名称首字母的小写‘b’。 mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b'; 为了找出以“fy”结尾的名字,使用“$”匹配名字的结尾:内容来自Sqlclub.cnmysql> SELECT * FROM pet WHERE name REGEXP 'fy$'; +--------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +--------+--------+---------+------+------------+-------+ | Fluffy | Harold | cat | f | 1993-02-04 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +--------+--------+---------+------+------------+-------+ 为了找出包含一个“w”的名字,使用以下查询: mysql> SELECT * FROM pet WHERE name REGEXP 'w'; +----------+-------+---------+------+------------+------------+ | name | owner | species | sex | birth | death | +----------+-------+---------+------+------------+------------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | copyright Sqlclub | Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 | | Whistler | Gwen | bird | NULL | 1997-12-09 | NULL | +----------+-------+---------+------+------------+------------+ 既然如果一个正则表达式出现在值的任何地方,其模式匹配了,就不必在先前的查询中在模式的两侧放置一个通配符以使得它匹配整个值,就像你使用了一个SQL模式那样。 为了找出包含正好5个字符的名字,使用“^”和“$”匹配名字的开始和结尾,和5个“.”实例在两者之间: mysql> SELECT * FROM pet WHERE name REGEXP '^.....$'; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | Sqlclub | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+ 你也可以使用“{n}”“重复n次”操作符重写前面的查询: mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$'; +-------+--------+---------+------+------------+-------+ | name | owner | species | sex | birth | death | +-------+--------+---------+------+------------+-------+ | Claws | Gwen | cat | m | 1994-03-17 | NULL | | Buffy | Harold | dog | f | 1989-05-13 | NULL | +-------+--------+---------+------+------------+-------+附录G:MySQL正则表达式 提供了关于正则表达式的句法的详细信息。 3.3.4.8. 计数行数据库经常用于回答这个问题,“某个类型的数据在表中出现的频度?”例如,你可能想要知道你有多少宠物,或每位主人有多少宠物,或你可能想要对你的动物进行各种类型的普查。Sqlclub学习社区计算你拥有动物的总数目与“在pet表中有多少行?”是同样的问题,因为每个宠物有一个记录。COUNT(*)函数计算行数,所以计算动物数目的查询应为: mysql> SELECT COUNT(*) FROM pet; +----------+ | COUNT(*) | +----------+ | 9 | +----------+ 在前面,你检索了拥有宠物的人的名字。如果你想要知道每个主人有多少宠物,你可以使用COUNT( )函数: mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner; +--------+----------+ | owner | COUNT(*) | +--------+----------+ | Benny | 2 | | Diane | 2 | | Gwen | 3 | | Harold | 2 | +--------+----------+ 注意,使用GROUP BY对每个owner的所有记录分组,没有它,你会得到错误消息:copyright Sqlclubmysql> SELECT owner, COUNT(*) FROM pet; ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause COUNT( )和GROUP BY以各种方式分类你的数据。下列例子显示出进行动物普查操作的不同方式。 每种动物的数量: mysql> SELECT species, COUNT(*) FROM pet GROUP BY species; +---------+----------+ | species | COUNT(*) | +---------+----------+ | bird | 2 | | cat | 2 | | dog | 3 | | hamster | 1 | | snake | 1 | +---------+----------+ 每种性别的动物数量: mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex; +------+----------+ | sex | COUNT(*) | Sqlclub.cn +------+----------+ | NULL | 1 | | f | 4 | | m | 4 | +------+----------+ (在这个输出中,NULL表示“未知性别”。) 按种类和性别组合的动物数量: mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex; +---------+------+----------+ | species | sex | COUNT(*) | +---------+------+----------+ | bird | NULL | 1 | | bird | f | 1 | | cat | f | 1 | | cat | m | 1 | | dog | f | 1 |Sqlclub.cn| dog | m | 2 | | hamster | f | 1 | | snake | m | 1 | +---------+------+----------+ 若使用COUNT( ),你不必检索整个表。例如, 前面的查询,当只对狗和猫进行时,应为: mysql> SELECT species, sex, COUNT(*) FROM pet -> WHERE species = 'dog' OR species = 'cat' -> GROUP BY species, sex; +---------+------+----------+ | species | sex | COUNT(*) | +---------+------+----------+ | cat | f | 1 | | cat | m | 1 | | dog | f | 1 | 本文来自Sqlclub | dog | m | 2 | +---------+------+----------+ 或,如果你仅需要知道已知性别的按性别的动物数目: mysql> SELECT species, sex, COUNT(*) FROM pet -> WHERE sex IS NOT NULL -> GROUP BY species, sex; +---------+------+----------+ | species | sex | COUNT(*) | +---------+------+----------+ | bird | f | 1 | | cat | f | 1 | | cat | m | 1 | | dog | f | 1 | | dog | m | 2 | Sqlclub学习社区| hamster | f | 1 | | snake | m | 1 | +---------+------+----------+ 3.3.4.9. 使用1个以上的表 pet表追踪你有哪个宠物。如果你想要记录其它相关信息,例如在他们一生中看兽医或何时后代出生,你需要另外的表。这张表应该像什么呢?需要: · 它需要包含宠物名字以便你知道每个事件属于哪个动物。 · 需要一个日期以便你知道事件是什么时候发生的。 · 需要一个描述事件的字段。 · 如果你想要对事件进行分类,则需要一个事件类型字段。 综合上述因素,event表的CREATE TABLE语句应为: mysql> CREATE TABLE event (name VARCHAR(20), date DATE, Sqlclub -> type VARCHAR(15), re VARCHAR(255)); 对于pet表,最容易的方法是创建包含信息的用定位符分隔的文本文件来装载初始记录: name date type reFluffy 1995-05-15 litter 4 kittens, 3 female, 1 maleBuffy 1993-06-23 litter 5 puppies, 2 female, 3 maleBuffy 1994-06-19 litter 3 puppies, 3 femaleChirpy 1999-03-21 vet needed beak straightenedSlim 1997-08-03 vet broken ribBowser 1991-10-12 kennel Fang 1991-10-12 kennel Fang 1998-08-28 birthday Gave him a new chew toyClaws 1998-03-17 birthday Gave him a new flea collarWhistler 1998-12-09 birthday First birthday采用如下方式装载记录: mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event; Sqlclub
上面是详细的解答挂于比表达式的用法产生新的问题如下如果区某个字段里面只存在一个小写字母 w的语句 前面例子的SELECT * FROM pet WHERE name REGEXP 'w'; 是错误的 他会取出重复n次的w字母的会抽出来。现在要求只出现一次w的字段值
8.格式化输出 我们能让动作显示一些比较复杂的结果。例如: gawk ’$1 != "Tim" {print $1,$ 5,$ 6,$2}’ testfile 将显示testfile文件中所有第一个字段和Ti m不相同的记录的第一、第五、第六和第二个字段。 进一步,你能在p r i n t动作中加入字符串,例如: gawk ’$1 != "Tim" {print "The entry for ",$ 1,"is not Tim. ",$2}’ testfile print动作的每一部分用逗号隔开。 借用C语言的格式化输出指令,能让gawk的输出形式更为多样。这时,应该用printf而不是print。例如: {printf "%5s likes this language\n",$ 2 } printf中的%5s 部分告诉gawk怎么格式化输出字符串,也就是输出5个字符长。他的值由printf 的最后部分指出,在此是第二个字段。\n是回车换行符。如果第二个字段中存储的是人名,则输出结果大致如下: Tim likes this language Geoff likes this language Mike likes this language Joe likes this language gawk 语言支持的其他格式控制符号如下: • c 如果是字符串,则显示第一个字符;如果是整数,则将数字以ASCII 字符的形式显示。 例如: printf “% c”,65 结果将显示字母A。 • d 显示十进制的整数。 • i 显示十进制的整数。 • e 将浮点数以科学记数法的形式显示。 例如: print “$ 4 . 3 e”,1950 结果将显示1.950e+03。 • f 将数字以浮点的形式显示。 • g 将数字以科学记数法的形式或浮点的形式显示。数字的绝对值如果大于等于0 . 0 0 0 1则 以浮点的形式显示,否则以科学记数法的形式显示。 • o 显示无符号的八进制整数。 • s 显示一个字符串。 • x 显示无符号的十六进制整数。1 0至1 5以a至f表示。 • X 显示无符号的十六进制整数。1 0至1 5以A至F表示。 • % 他并不是真正的格式控制字符,% %将显示%。 当你使用这些格式控制字符时,你能在控制字符前给出数字,以表示你将用的几位或几个字符。例如,6 d表示一个整数有6位。再请看下面的例子: {printf "%5s works for %5s and earns %2d an hour",$1,$2,$3} 将会产生类似如下的输出: Joe works for Mike and earns 12 an hour 当处理数据时,你能指定数据的精确位数 {printf "%5s earns $%.2f an hour",$ 3,$ 6 } 其输出将类似于: Joe earns $12.17 an hour 你也能使用一些换码控制符格式化整行的输出。之所以叫做换码控制符,是因为gawk对这些符号有特别的解释。下面列出常用的换码控制符: \a 警告或响铃字符。 \b 后退一格。 \f 换页。 \n 换行。 \r 回车。 \t Ta b。 \v 垂直的t a b。 9.改动字段分隔符 在g a w k中,缺省的字段分隔符一般是空格符或TA B。但你能在命令行使用- F选项改动字符分隔符,只需在- F后面跟着你想用的分隔符即可。 gawk -F" ;"’/tparker/{print}’ /etc/passwd 在此例中,你将字符分隔符设置成分号。注意: - F必须是大写的,而且必须在第一个引号之前。 10.元字符 gawk语言在格式匹配时有其特别的规则。例如, cat能够和记录中所有位置有这三个字符的字段匹配。但有时你需要一些更为特别的匹配。如果你想让cat只和concatenate匹配,则需要在格式两端加上空格: / cat / {print} 再例如,你希望既和cat又和CAT匹配,则能使用或(|): / cat | CAT / {print} 在gawk中,有几个字符有特别意义。下面列出能用在gawk格式中的这些字符: • ^ 表示字段的开始。 例如: $3 ~ /^b/ 如果第三个字段以字符b开始,则匹配。 • $ 表示字段的结束。 例如: $3 ~ /b$/ 如果第三个字段以字符b结束,则匹配。 • . 表示和所有单字符m匹配。 例如: $3 ~ /i.m/ 如果第三个字段有字符i,则匹配。 • | 表示“或”。 例如: / c a t | C AT/ 和cat 或C AT字符匹配。 • * 表示字符的零到多次重复。 例如: /UNI*X/ 和U N X、U N I X、U N I I X、U N I I I X等匹配。 • + 表示字符的一次到多次重复。 例如: /UNI+X/ 和U N I X、U N I I X等匹配。 • \{a,b\} 表示字符a次到b次之间的重复。 例如: / U N I \ { 1,3 \ } X 和U N I X、U N I I X和U N I I I X匹配。 • ? 表示字符零次和一次的重复。 例如: /UNI?X/ 和UNX 和U N I X匹配。 • [] 表示字符的范围。 例如: /I[BDG]M/ 和I B M、I D M和I G M匹配 • [^] 表示不在[ ]中的字符。 例如: /I[^DE]M/ 和所有的以I开始、M结束的包括三个字符的字符串匹配,除了IDM和IEM之外。 11.调用gawk程式 当需要非常多对模式和动作时,你能编写一个gawk程式(也叫做gawk脚本)。在gawk程式中,你能省略模式和动作两边的引号,因为在gawk程式中,模式和动作从哪开始和从哪结束时是非常显然的。 你能使用如下命令调用g a w k程式: gawk -f scrīpt filename 此命令使gawk对文件filename执行名为scrīpt的gawk程式。 如果你不希望使用缺省的字段分隔符,你能在f选项后面跟着F选项指定新的字段分隔符(当然你也能在gawk程式中指定),例如,使用分号作为字段分隔符: gawk -f scrīpt -F";" filename 如果希望gawk 程式处理多个文件,则把各个文件名罗列其后: gawk -f scrīpt filename1 filename2 filename3 ... 缺省情况下, gawk的输出将送往屏幕。但你能使用Linux的重定向命令使gawk的输出送往一个文件: gawk -f scrīpt filename > save_file 12.BEGIN和END 有两个特别的模式在gawk中非常有用。BEGIN模式用来指明gawk开始处理一个文件之前执行一些动作。BEGIN经常用来初始化数值,设置参数等。END模式用来在文件处理完成后执行一些指令,一般用作总结或注释。 BEGIN 和END中所有要执行的指令都应该用花括号括起来。BEGIN 和END必须使用大写。 请看下面的例子: BEGIN { print "Starting the process the file" } $1 == "UNIX" {print} $2 > 10 {printf "This line has a value of %d",$ 2 } END { print "Finished processing the file. Bye!"} 此程式中,先显示一条信息: Starting the process the file,然后将所有第一个字段等于 UNIX的整条记录显示出来,然后再显示第二个字段大于10 的记录,最后显示信息: Finished processing the file. Bye! 13.变量 在gawk中,能用等号( = )给一个变量赋值: var1=10 在gawk中,你不必事先声明变量类型。 请看下面的例子: $1 == "Plastic" { count = count + 1 } 如果第一个字段是Plastic,则count的值加1。在此之前,我们应当给count赋予过初值,一般是在BEGIN部分。 下面是比较完整的例子: BEGIN { count = 0 } $5 == "UNIX" { count = count + 1 } END { printf "%d occurrences of UNIX were found",count } 变量能和字段和数值一起使用,所以,下面的表达式均为合法: count = count + $6 count = $5 - 8 count = $5 + var1 变量也能是格式的一部分,例如: $2 > max_value {print "Max value exceeded by ",$2 - max_value} $4 - var1 $2){ print "The first column is larger" } else { print "The second column is larger" } ) 15.2 while 循环 while 循环的语法如下: while (expression){ c o m m a n d s } 例如: # interest calculation computes compound interest # inputs from a file are the amount,interest_rateand years {var = 1 while (var 0){ print line[var] v a r - - } } 此段程式读取一个文件的每一行,并用相反的顺序显示出来。我们使用NR作为数组的下标来存储文件的每一条记录,然后在从最后一条记录开始,将文件逐条地显示出来。 17.用户自定义函数 复杂的gawk 程式常常能使用自己定义的函数来简化。调用用户自定义函数和调用内部函数的方法相同。函数的定义能放在gawk 程式的所有地方。 用户自定义函数的格式如下: function name (parameter-list) { b o d y - o f - f u n c t i o n } name 是所定义的函数的名称。一个正确的函数名称可包括一序列的字母、数字、下标线(underscores),不过不可用数字做开头。parameter- list 是函数的全部参数的列表,各个参数之间以逗点隔开。body-of-function 包含gawk 的表达式,他是函数定义里最重要的部分,他决定函数实际要做的事情。 下面这个例子,会将每个记录的第一个字段的值的平方和第二个字段的值的平方加起来。 {print "sum =",S q u a r e S u m ( $ 1,$ 2 ) } function SquareSum(x,y) { s u m = x * x + y * y return sum } 到此,我们已知道了gawk的基本用法。gawk语言十分易学好用,例如,你能用gawk编写一段小程式来计算一个目录中所有文件的个数和容量。如果用其他的语言,如C语言,则会十分的麻烦,相反,gawk只需要几行就能完成此工作。 18.几个实例 最后,再举几个gawk的例子: gawk ’{if (NF > max) max = NF} END {print max}’ 此程式会显示所有输入行之中字段的最大个数。 gawk ’length($0) > 80’ 此程式会显示出超过80 个字符的每一行。此处只有模式被列出,动作是采用缺省值显示整个记录。 gawk ’NF > 0’ 显示拥有至少一个字段的所有行。这是个简单的方法,将一个文件里的所有空白行删除。 gawk ’BEGIN {for (i = 1; igrep grep (global search regular expression(RE) and print out the line,全方面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,他能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有非常小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,他们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特别。linux使用GNU版本的grep。他功能更强,能通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。 grep的工作方式是这样的:他在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。 grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。 1. grep正则表达式元字符集(基本集) ^ 锚定行的开始 如:’^grep’匹配所有以grep开头的行。 $ 锚定行的结束 如:’grep$’匹配所有以grep结尾的行。 . 匹配一个非换行符的字符 如:’gr.p’匹配gr后接一个任意字符,然后是p。 * 匹配零个或多个先前字符 如:’*grep’匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。 [] 匹配一个指定范围内的字符,如’[Gg]rep’匹配Grep和grep。 [^] 匹配一个不在指定范围内的字符,如:’[^A-FH-Z]rep’匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。 \(..\) 标记匹配字符,如’\(love\)’,love被标记为1。 \锚定单词的开始,如:’\匹配包含以grep开头的单词的行。 \> 锚定单词的结束,如’grep\>’匹配包含以grep结尾的单词的行。 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的行。 \w 匹配文字和数字字符,也就是[A-Za-z0-9],如:’G\w*p’匹配以G后跟零个或多个文字或数字字符,然后是p。 \W \w的反置形式,匹配一个或多个非单词字符,如点号句号等。 \b 单词锁定符,如: ’\bgrepb\’只匹配grep。 2. 用于egrep和 grep -E的元字符扩展集 + 匹配一个或多个先前的字符。如:’[a-z]+able’,匹配一个或多个小写字母后跟able的串,如loveable,enable,disable等。 ? 匹配零个或多个先前的字符。如:’gr?p’匹配gr后跟一个或没有字符,然后是p的行。 a|b|c 匹配a或b或c。如:grep|sed匹配grep或sed () 分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。 x{m},x{m,},x{m,n} 作用同x\{m\},x\{m,\},x\{m,n\} 4. POSIX字符类 为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)增加了特别的字符类,如[:alnum:]是A-Za-z0-9的另一个写法。要把他们放到[]号内才能成为正则表达式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。 [:alnum:] 文字数字字符 [:alpha:]文字字符 [:digit:] 数字字符 [:graph:] 非空字符(非空格、控制字符) [:lower:] 小写字符 [:cntrl:] 控制字符 [:print:] 非空字符(包括空格) [:punct:] 标点符号 [:space:] 所有空白字符(新行,空格,制表符) [:upper:] 大写字符 [:xdigit:] 十六进制数字(0-9,a-f,A-F) 4. Grep命令选项 -? 同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。 -b,--byte-offset 打印匹配行前面打印该行所在的块号码。 -c,--count 只打印匹配的行数,不显示匹配的内容。 -f File,--file=File 从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。 -h,--no-filename 当搜索多个文件时,不显示匹配文件名前缀。 -i,--ignore-case 忽略大小写差别。 -q,--quiet 取消显示,只返回退出状态。0则表示找到了匹配的行。 -l,--files-with-matches 打印匹配模板的文件清单。 -L,--files-without-match 打印不匹配模板的文件清单。 -n,--line-number 在匹配的行前面打印行号。 -s,--silent 不显示关于不存在或无法读取文件的错误信息。 -v,--revert-match 反检索,只显示不匹配的行。 -w,--word-regexp 如果被\和\>引用,就把表达式做为一个单词搜索。 -V,--version 显示 软件 版本信息。 5. 实例 要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。 $ ls -l | grep ’^a’ 通过管道过滤ls -l输出的内容,只显示以a开头的行。 $ grep ’test’ d* 显示所有以d开头的文件中包含test的行。 $ grep ’test’ aa bb cc 显示在aa,bb,cc文件中匹配test的行。 $ grep ’[a-z]\{5\}’ aa 显示所有包含每个字符串至少有5个连续小写字符的字符串的行。 $ grep ’w\(es\)t.*\1’ aa 如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用"\"号进行转义,直接写成’w(es)t.*\1’就能了。
+----------------------------------------------------------------+
| ' **testettestestes** ' regexp ' [*][*]testettestestes[*][*] ' |
+----------------------------------------------------------------+
| 1 |
+----------------------------------------------------------------+
1 row in set (0.00 sec)mysql>
ysql> select ' 45testettestestes12' regexp ' [*][*]testettestestes[*][*] ';
+---------------------------------------------------------------+
| ' 45testettestestes12' regexp ' [*][*]testettestestes[*][*] ' |
+---------------------------------------------------------------+
| 0 |
+---------------------------------------------------------------+
1 row in set (0.00 sec)mysql> select ' 45testettestestes12' regexp ' [0-9][0-9]testettestestes[0-9][0-9]';
+----------------------------------------------------------------------+
| ' 45testettestestes12' regexp ' [0-9][0-9]testettestestes[0-9][0-9]' |
+----------------------------------------------------------------------+
| 1 |
+----------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> select ' s5testettestestes12' regexp ' %testettestestes[0-9][0-9]';+-------------------------------------------------------------+
| ' s5testettestestes12' regexp ' %testettestestes[0-9][0-9]' |
+-------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)testettestestes[ 前面允许任意个数的字符或者数字 以前可以用%但是现在失败
mysql> select ' s5testettestestes12' regexp ' *testettestestes[0-9][0-9]';
+-------------------------------------------------------------+
| ' s5testettestestes12' regexp ' *testettestestes[0-9][0-9]' |
+-------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)mysql replace用法1.replace into
replace into table (id,name) values('1','aa'),('2','bb')
此语句的作用是向表table中插入两条记录。如果主键id为1或2不存在
就相当于
insert into table (id,name) values('1','aa'),('2','bb')
如果存在相同的值则不会插入数据2.replace(object,search,replace)
把object中出现search的全部替换为replace
select replace('www.163.com','w','Ww')--->WwWwWw.163.com
例:把表table中的name字段中的aa替换为bb
update table set name=replace(name,'aa','bb')
--------------------------------------------------------------------------------
由MySQL提供的模式匹配的其它类型是使用扩展正则表达式。当你对这类模式进行匹配测试时,使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它们是同义词)。
扩展正则表达式的一些字符是:
· ‘.’匹配任何单个的字符。 copyright Sqlclub
· 字符类“[...]”匹配在方括号内的任何字符。例如,“[abc]”匹配“a”、“b”或“c”。为了命名字符的范围,使用一个“-”。“[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。
· “ * ”匹配零个或多个在它前面的字符。例如,“x*”匹配任何数量的“x”字符,“[0-9]*”匹配任何数量的数字,而“.*”匹配任何数量的任何字符。
如果REGEXP模式与被测试值的任何地方匹配,模式就匹配(这不同于LIKE模式匹配,只有与整个值匹配,模式才匹配)。
为了定位一个模式以便它必须匹配被测试值的开始或结尾,在模式开始处使用“^”或在模式的结尾用“$”。
为了说明扩展正则表达式如何工作,下面使用REGEXP重写上面所示的LIKE查询:
Sqlclub为了找出以“b”开头的名字,使用“^”匹配名字的开始:
mysql> SELECT * FROM pet WHERE name REGEXP '^b';
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
如果你想强制使REGEXP比较区分大小写,使用BINARY关键字使其中一个字符串变为二进制字符串。该查询只匹配名称首字母的小写‘b’。
mysql> SELECT * FROM pet WHERE name REGEXP BINARY '^b';
为了找出以“fy”结尾的名字,使用“$”匹配名字的结尾:内容来自Sqlclub.cnmysql> SELECT * FROM pet WHERE name REGEXP 'fy$';
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+--------+--------+---------+------+------------+-------+
为了找出包含一个“w”的名字,使用以下查询:
mysql> SELECT * FROM pet WHERE name REGEXP 'w';
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL | copyright Sqlclub
| Bowser | Diane | dog | m | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
+----------+-------+---------+------+------------+------------+
既然如果一个正则表达式出现在值的任何地方,其模式匹配了,就不必在先前的查询中在模式的两侧放置一个通配符以使得它匹配整个值,就像你使用了一个SQL模式那样。
为了找出包含正好5个字符的名字,使用“^”和“$”匹配名字的开始和结尾,和5个“.”实例在两者之间:
mysql> SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL | Sqlclub
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+
你也可以使用“{n}”“重复n次”操作符重写前面的查询:
mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$';
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
+-------+--------+---------+------+------------+-------+附录G:MySQL正则表达式 提供了关于正则表达式的句法的详细信息。
3.3.4.8. 计数行数据库经常用于回答这个问题,“某个类型的数据在表中出现的频度?”例如,你可能想要知道你有多少宠物,或每位主人有多少宠物,或你可能想要对你的动物进行各种类型的普查。Sqlclub学习社区计算你拥有动物的总数目与“在pet表中有多少行?”是同样的问题,因为每个宠物有一个记录。COUNT(*)函数计算行数,所以计算动物数目的查询应为:
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
| 9 |
+----------+
在前面,你检索了拥有宠物的人的名字。如果你想要知道每个主人有多少宠物,你可以使用COUNT( )函数:
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
+--------+----------+
| owner | COUNT(*) |
+--------+----------+
| Benny | 2 |
| Diane | 2 |
| Gwen | 3 |
| Harold | 2 |
+--------+----------+
注意,使用GROUP BY对每个owner的所有记录分组,没有它,你会得到错误消息:copyright Sqlclubmysql> SELECT owner, COUNT(*) FROM pet;
ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
with no GROUP columns is illegal if there is no GROUP BY clause
COUNT( )和GROUP BY以各种方式分类你的数据。下列例子显示出进行动物普查操作的不同方式。
每种动物的数量:
mysql> SELECT species, COUNT(*) FROM pet GROUP BY species;
+---------+----------+
| species | COUNT(*) |
+---------+----------+
| bird | 2 |
| cat | 2 |
| dog | 3 |
| hamster | 1 |
| snake | 1 |
+---------+----------+
每种性别的动物数量:
mysql> SELECT sex, COUNT(*) FROM pet GROUP BY sex;
+------+----------+
| sex | COUNT(*) | Sqlclub.cn
+------+----------+
| NULL | 1 |
| f | 4 |
| m | 4 |
+------+----------+
(在这个输出中,NULL表示“未知性别”。)
按种类和性别组合的动物数量:
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | NULL | 1 |
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |Sqlclub.cn| dog | m | 2 |
| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
若使用COUNT( ),你不必检索整个表。例如, 前面的查询,当只对狗和猫进行时,应为:
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE species = 'dog' OR species = 'cat'
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 | 本文来自Sqlclub
| dog | m | 2 |
+---------+------+----------+
或,如果你仅需要知道已知性别的按性别的动物数目:
mysql> SELECT species, sex, COUNT(*) FROM pet
-> WHERE sex IS NOT NULL
-> GROUP BY species, sex;
+---------+------+----------+
| species | sex | COUNT(*) |
+---------+------+----------+
| bird | f | 1 |
| cat | f | 1 |
| cat | m | 1 |
| dog | f | 1 |
| dog | m | 2 |
Sqlclub学习社区| hamster | f | 1 |
| snake | m | 1 |
+---------+------+----------+
3.3.4.9. 使用1个以上的表
pet表追踪你有哪个宠物。如果你想要记录其它相关信息,例如在他们一生中看兽医或何时后代出生,你需要另外的表。这张表应该像什么呢?需要:
· 它需要包含宠物名字以便你知道每个事件属于哪个动物。
· 需要一个日期以便你知道事件是什么时候发生的。
· 需要一个描述事件的字段。
· 如果你想要对事件进行分类,则需要一个事件类型字段。
综合上述因素,event表的CREATE TABLE语句应为:
mysql> CREATE TABLE event (name VARCHAR(20), date DATE, Sqlclub
-> type VARCHAR(15), re VARCHAR(255));
对于pet表,最容易的方法是创建包含信息的用定位符分隔的文本文件来装载初始记录:
name
date
type
reFluffy
1995-05-15
litter
4 kittens, 3 female, 1 maleBuffy
1993-06-23
litter
5 puppies, 2 female, 3 maleBuffy
1994-06-19
litter
3 puppies, 3 femaleChirpy
1999-03-21
vet
needed beak straightenedSlim
1997-08-03
vet
broken ribBowser
1991-10-12
kennel
Fang
1991-10-12
kennel
Fang
1998-08-28
birthday
Gave him a new chew toyClaws
1998-03-17
birthday
Gave him a new flea collarWhistler
1998-12-09
birthday
First birthday采用如下方式装载记录:
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;
Sqlclub
前面例子的SELECT * FROM pet WHERE name REGEXP 'w'; 是错误的
他会取出重复n次的w字母的会抽出来。现在要求只出现一次w的字段值
+----------------------------------+
| 'aaawfff' regexp '^[^w]*w[^w]*$' |
+----------------------------------+
| 1 |
+----------------------------------+
1 row in set (0.00 sec)mysql> select 'aawawfff' regexp '^[^w]*w[^w]*$';
+-----------------------------------+
| 'aawawfff' regexp '^[^w]*w[^w]*$' |
+-----------------------------------+
| 0 |
+-----------------------------------+
1 row in set (0.00 sec)mysql>
我们能让动作显示一些比较复杂的结果。例如:
gawk ’$1 != "Tim" {print $1,$ 5,$ 6,$2}’ testfile
将显示testfile文件中所有第一个字段和Ti m不相同的记录的第一、第五、第六和第二个字段。
进一步,你能在p r i n t动作中加入字符串,例如:
gawk ’$1 != "Tim" {print "The entry for ",$ 1,"is not
Tim. ",$2}’ testfile
print动作的每一部分用逗号隔开。
借用C语言的格式化输出指令,能让gawk的输出形式更为多样。这时,应该用printf而不是print。例如:
{printf "%5s likes this language\n",$ 2 }
printf中的%5s 部分告诉gawk怎么格式化输出字符串,也就是输出5个字符长。他的值由printf 的最后部分指出,在此是第二个字段。\n是回车换行符。如果第二个字段中存储的是人名,则输出结果大致如下:
Tim likes this language
Geoff likes this language
Mike likes this language
Joe likes this language
gawk 语言支持的其他格式控制符号如下:
• c 如果是字符串,则显示第一个字符;如果是整数,则将数字以ASCII 字符的形式显示。
例如:
printf “% c”,65
结果将显示字母A。
• d 显示十进制的整数。
• i 显示十进制的整数。
• e 将浮点数以科学记数法的形式显示。
例如:
print “$ 4 . 3 e”,1950
结果将显示1.950e+03。
• f 将数字以浮点的形式显示。
• g 将数字以科学记数法的形式或浮点的形式显示。数字的绝对值如果大于等于0 . 0 0 0 1则
以浮点的形式显示,否则以科学记数法的形式显示。
• o 显示无符号的八进制整数。
• s 显示一个字符串。
• x 显示无符号的十六进制整数。1 0至1 5以a至f表示。
• X 显示无符号的十六进制整数。1 0至1 5以A至F表示。
• % 他并不是真正的格式控制字符,% %将显示%。
当你使用这些格式控制字符时,你能在控制字符前给出数字,以表示你将用的几位或几个字符。例如,6 d表示一个整数有6位。再请看下面的例子:
{printf "%5s works for %5s and earns %2d an hour",$1,$2,$3}
将会产生类似如下的输出:
Joe works for Mike and earns 12 an hour
当处理数据时,你能指定数据的精确位数
{printf "%5s earns $%.2f an hour",$ 3,$ 6 }
其输出将类似于:
Joe earns $12.17 an hour
你也能使用一些换码控制符格式化整行的输出。之所以叫做换码控制符,是因为gawk对这些符号有特别的解释。下面列出常用的换码控制符:
\a 警告或响铃字符。
\b 后退一格。
\f 换页。
\n 换行。
\r 回车。
\t Ta b。
\v 垂直的t a b。
9.改动字段分隔符
在g a w k中,缺省的字段分隔符一般是空格符或TA B。但你能在命令行使用- F选项改动字符分隔符,只需在- F后面跟着你想用的分隔符即可。
gawk -F" ;"’/tparker/{print}’ /etc/passwd
在此例中,你将字符分隔符设置成分号。注意: - F必须是大写的,而且必须在第一个引号之前。
10.元字符
gawk语言在格式匹配时有其特别的规则。例如, cat能够和记录中所有位置有这三个字符的字段匹配。但有时你需要一些更为特别的匹配。如果你想让cat只和concatenate匹配,则需要在格式两端加上空格:
/ cat / {print}
再例如,你希望既和cat又和CAT匹配,则能使用或(|):
/ cat | CAT / {print}
在gawk中,有几个字符有特别意义。下面列出能用在gawk格式中的这些字符:
• ^ 表示字段的开始。
例如:
$3 ~ /^b/
如果第三个字段以字符b开始,则匹配。
• $ 表示字段的结束。
例如:
$3 ~ /b$/
如果第三个字段以字符b结束,则匹配。
• . 表示和所有单字符m匹配。
例如:
$3 ~ /i.m/
如果第三个字段有字符i,则匹配。
• | 表示“或”。
例如:
/ c a t | C AT/
和cat 或C AT字符匹配。
• * 表示字符的零到多次重复。
例如:
/UNI*X/
和U N X、U N I X、U N I I X、U N I I I X等匹配。
• + 表示字符的一次到多次重复。
例如:
/UNI+X/
和U N I X、U N I I X等匹配。
• \{a,b\} 表示字符a次到b次之间的重复。
例如:
/ U N I \ { 1,3 \ } X
和U N I X、U N I I X和U N I I I X匹配。
• ? 表示字符零次和一次的重复。
例如:
/UNI?X/
和UNX 和U N I X匹配。
• [] 表示字符的范围。
例如:
/I[BDG]M/
和I B M、I D M和I G M匹配
• [^] 表示不在[ ]中的字符。
例如:
/I[^DE]M/
和所有的以I开始、M结束的包括三个字符的字符串匹配,除了IDM和IEM之外。
11.调用gawk程式
当需要非常多对模式和动作时,你能编写一个gawk程式(也叫做gawk脚本)。在gawk程式中,你能省略模式和动作两边的引号,因为在gawk程式中,模式和动作从哪开始和从哪结束时是非常显然的。
你能使用如下命令调用g a w k程式:
gawk -f scrīpt filename
此命令使gawk对文件filename执行名为scrīpt的gawk程式。
如果你不希望使用缺省的字段分隔符,你能在f选项后面跟着F选项指定新的字段分隔符(当然你也能在gawk程式中指定),例如,使用分号作为字段分隔符:
gawk -f scrīpt -F";" filename
如果希望gawk 程式处理多个文件,则把各个文件名罗列其后:
gawk -f scrīpt filename1 filename2 filename3 ...
缺省情况下, gawk的输出将送往屏幕。但你能使用Linux的重定向命令使gawk的输出送往一个文件:
gawk -f scrīpt filename > save_file
12.BEGIN和END
有两个特别的模式在gawk中非常有用。BEGIN模式用来指明gawk开始处理一个文件之前执行一些动作。BEGIN经常用来初始化数值,设置参数等。END模式用来在文件处理完成后执行一些指令,一般用作总结或注释。
BEGIN 和END中所有要执行的指令都应该用花括号括起来。BEGIN 和END必须使用大写。
请看下面的例子:
BEGIN { print "Starting the process the file" }
$1 == "UNIX" {print}
$2 > 10 {printf "This line has a value of %d",$ 2 }
END { print "Finished processing the file. Bye!"}
此程式中,先显示一条信息: Starting the process the file,然后将所有第一个字段等于
UNIX的整条记录显示出来,然后再显示第二个字段大于10 的记录,最后显示信息: Finished processing the file. Bye!
13.变量
在gawk中,能用等号( = )给一个变量赋值:
var1=10
在gawk中,你不必事先声明变量类型。
请看下面的例子:
$1 == "Plastic" { count = count + 1 }
如果第一个字段是Plastic,则count的值加1。在此之前,我们应当给count赋予过初值,一般是在BEGIN部分。
下面是比较完整的例子:
BEGIN { count = 0 }
$5 == "UNIX" { count = count + 1 }
END { printf "%d occurrences of UNIX were found",count }
变量能和字段和数值一起使用,所以,下面的表达式均为合法:
count = count + $6
count = $5 - 8
count = $5 + var1
变量也能是格式的一部分,例如:
$2 > max_value {print "Max value exceeded by ",$2 - max_value}
$4 - var1 $2){
print "The first column is larger"
}
else {
print "The second column is larger"
} )
15.2 while 循环
while 循环的语法如下:
while (expression){
c o m m a n d s
}
例如:
# interest calculation computes compound interest
# inputs from a file are the amount,interest_rateand years
{var = 1
while (var 0){
print line[var]
v a r - -
}
}
此段程式读取一个文件的每一行,并用相反的顺序显示出来。我们使用NR作为数组的下标来存储文件的每一条记录,然后在从最后一条记录开始,将文件逐条地显示出来。
17.用户自定义函数
复杂的gawk 程式常常能使用自己定义的函数来简化。调用用户自定义函数和调用内部函数的方法相同。函数的定义能放在gawk 程式的所有地方。
用户自定义函数的格式如下:
function name (parameter-list) {
b o d y - o f - f u n c t i o n
}
name 是所定义的函数的名称。一个正确的函数名称可包括一序列的字母、数字、下标线(underscores),不过不可用数字做开头。parameter-
list 是函数的全部参数的列表,各个参数之间以逗点隔开。body-of-function 包含gawk 的表达式,他是函数定义里最重要的部分,他决定函数实际要做的事情。
下面这个例子,会将每个记录的第一个字段的值的平方和第二个字段的值的平方加起来。
{print "sum =",S q u a r e S u m ( $ 1,$ 2 ) }
function SquareSum(x,y) {
s u m = x * x + y * y
return sum
}
到此,我们已知道了gawk的基本用法。gawk语言十分易学好用,例如,你能用gawk编写一段小程式来计算一个目录中所有文件的个数和容量。如果用其他的语言,如C语言,则会十分的麻烦,相反,gawk只需要几行就能完成此工作。
18.几个实例
最后,再举几个gawk的例子:
gawk ’{if (NF > max) max = NF}
END {print max}’
此程式会显示所有输入行之中字段的最大个数。
gawk ’length($0) > 80’
此程式会显示出超过80 个字符的每一行。此处只有模式被列出,动作是采用缺省值显示整个记录。
gawk ’NF > 0’
显示拥有至少一个字段的所有行。这是个简单的方法,将一个文件里的所有空白行删除。
gawk ’BEGIN {for (i = 1; igrep
grep (global search regular expression(RE) and print out the line,全方面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,他能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有非常小不同。egrep是grep的扩展,支持更多的re元字符, fgrep就是fixed grep或fast grep,他们把所有的字母都看作单词,也就是说,正则表达式中的元字符表示回其自身的字面意义,不再特别。linux使用GNU版本的grep。他功能更强,能通过-G、-E、-F命令行选项来使用egrep和fgrep的功能。
grep的工作方式是这样的:他在一个或多个文件中搜索字符串模板。如果模板包括空格,则必须被引用,模板后的所有字符串被看作文件名。搜索的结果被送到屏幕,不影响原文件内容。
grep可用于shell脚本,因为grep通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回0,如果搜索不成功,则返回1,如果搜索的文件不存在,则返回2。我们利用这些返回值就可进行一些自动化的文本处理工作。
1. grep正则表达式元字符集(基本集)
^ 锚定行的开始 如:’^grep’匹配所有以grep开头的行。
$ 锚定行的结束 如:’grep$’匹配所有以grep结尾的行。
. 匹配一个非换行符的字符 如:’gr.p’匹配gr后接一个任意字符,然后是p。
* 匹配零个或多个先前字符 如:’*grep’匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。
[] 匹配一个指定范围内的字符,如’[Gg]rep’匹配Grep和grep。
[^] 匹配一个不在指定范围内的字符,如:’[^A-FH-Z]rep’匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。
\(..\) 标记匹配字符,如’\(love\)’,love被标记为1。
\锚定单词的开始,如:’\匹配包含以grep开头的单词的行。
\> 锚定单词的结束,如’grep\>’匹配包含以grep结尾的单词的行。
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的行。
\w 匹配文字和数字字符,也就是[A-Za-z0-9],如:’G\w*p’匹配以G后跟零个或多个文字或数字字符,然后是p。
\W \w的反置形式,匹配一个或多个非单词字符,如点号句号等。
\b 单词锁定符,如: ’\bgrepb\’只匹配grep。
2. 用于egrep和 grep -E的元字符扩展集
+ 匹配一个或多个先前的字符。如:’[a-z]+able’,匹配一个或多个小写字母后跟able的串,如loveable,enable,disable等。
? 匹配零个或多个先前的字符。如:’gr?p’匹配gr后跟一个或没有字符,然后是p的行。
a|b|c 匹配a或b或c。如:grep|sed匹配grep或sed
() 分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。
x{m},x{m,},x{m,n} 作用同x\{m\},x\{m,\},x\{m,n\}
4. POSIX字符类
为了在不同国家的字符编码中保持一至,POSIX(The Portable
Operating System Interface)增加了特别的字符类,如[:alnum:]是A-Za-z0-9的另一个写法。要把他们放到[]号内才能成为正则表达式,如[A- Za-z0-9]或[[:alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。
[:alnum:] 文字数字字符
[:alpha:]文字字符
[:digit:] 数字字符
[:graph:] 非空字符(非空格、控制字符)
[:lower:] 小写字符
[:cntrl:] 控制字符
[:print:] 非空字符(包括空格)
[:punct:] 标点符号
[:space:] 所有空白字符(新行,空格,制表符)
[:upper:] 大写字符
[:xdigit:] 十六进制数字(0-9,a-f,A-F)
4. Grep命令选项
-? 同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行。
-b,--byte-offset 打印匹配行前面打印该行所在的块号码。
-c,--count 只打印匹配的行数,不显示匹配的内容。
-f File,--file=File 从文件中提取模板。空文件中包含0个模板,所以什么都不匹配。
-h,--no-filename 当搜索多个文件时,不显示匹配文件名前缀。
-i,--ignore-case 忽略大小写差别。
-q,--quiet 取消显示,只返回退出状态。0则表示找到了匹配的行。
-l,--files-with-matches 打印匹配模板的文件清单。
-L,--files-without-match 打印不匹配模板的文件清单。
-n,--line-number 在匹配的行前面打印行号。
-s,--silent 不显示关于不存在或无法读取文件的错误信息。
-v,--revert-match 反检索,只显示不匹配的行。
-w,--word-regexp 如果被\和\>引用,就把表达式做为一个单词搜索。
-V,--version 显示
软件
版本信息。
5. 实例
要用好grep这个工具,其实就是要写好正则表达式,所以这里不对grep的所有功能进行实例讲解,只列几个例子,讲解一个正则表达式的写法。
$ ls -l | grep ’^a’
通过管道过滤ls -l输出的内容,只显示以a开头的行。
$ grep ’test’ d*
显示所有以d开头的文件中包含test的行。
$ grep ’test’ aa bb cc
显示在aa,bb,cc文件中匹配test的行。
$ grep ’[a-z]\{5\}’ aa
显示所有包含每个字符串至少有5个连续小写字符的字符串的行。
$ grep ’w\(es\)t.*\1’ aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(\1),找到就显示该行。如果用egrep或grep -E,就不用"\"号进行转义,直接写成’w(es)t.*\1’就能了。