shell通配符与正则表达式

    通配符是系统level的 而正则表达式需要相关工具的支持: egrep, awk, vi, perl。在文本过滤工具里,都是用正则表达式,比如像awk,sed等,是针对文件的内容的。通配符多用在文件名上,比如查找find,ls,cp,等等。

1.通配符      

(1)通配符语法:*      
* 将与零个或多个字符匹配。这就是说“什么都可以”。例子:      
  /etc/g* 与 /etc 中以 g 开头的所有文件匹配。      
  /tmp/my*1 与 /tmp 中以 my 开头,并且以 1 结尾的所有文件匹配。      
(2)通配符语法:?      
? 与任何单个字符匹配。例子:      
  myfile? 与文件名为 myfile 后跟单个字符的任何文件匹配。      
  /tmp/notes?txt 将与 /tmp/notes.txt 和 /tmp/notes_txt 都匹配,如果它们存在。      
(3)通配符语法:[]      
    该通配符与 ? 相似,但允许指定得更确切。要使用该通配符,把您想要匹配的所有字符放在 [] 内。结果的表达式将与 [] 中任一字符相匹配。您也可以用 – 来指定范围,甚至还可以组合范围。例子:      
    myfile[12] 将与 myfile1 和 myfile2 匹配。只要当前目录中至少有一个这样的文件存在,该通配符就可以进行扩展。      
    [Cc]hange[Ll]og 将与 Changelog、ChangeLog、changeLog 以及 changelog 匹配。您可以看到,与大写形式的变形匹配时,使用括弧通配符很有用。      
    ls /etc/[0-9]* 将列出 /etc 中以数字开头的所有文件。      
    ls /tmp/[A-Za-z]* 将列出 /tmp 中以大写字母或小写字母开头的所有文件。

(4)通配符语法:[!]       
    除了不与括弧中的任何字符匹配外,[!] 构造与 [] 构造类似,只要不是列在 [! 和 ] 之间的字符,它将与任何字符匹配。例子:        
     rm myfile[!9] 将删除除 myfile9 之外的名为 myfile 加一个字符的所有文件。        
    通配符告诫说明        
    这里有一些使用通配符时应该注意的告诫说明。由于 bash 对与通配符相关的字符(?、[、]、*)进行特别处理,因此您将包含这些字符的参数输入到命令中时,需要特别小心。例如,如果您想要创建一个包含字符串 [fo]* 的文件,下面这个命令可能不会执行您想要做的事:        
    $ echo [fo]* > /tmp/mynewfile.txt        
    如果 [fo]* 这个模式与当前工作目录中的任何文件匹配,那么您将在 /tmp/mynewfile.txt 内发现那些文件的名称,而不是您所期望的文字 [fo]*。解决方法是什么呢?嗯,一种方法是用单引号把这些字符括起来,这将告诉 bash 单纯地执行,而不会对其进行通配符扩展:        
    $ echo '[fo]*' > /tmp/mynewfile.txt        
采用这种方法,您的新文件将包含所期望的文字的 [fo]*。另一种方法是,您可以使用反斜杠,告诉 bash [、] 和 * 应该被当成文字处理,而不是被当成通配符处理:        
    $ echo \[fo\]\* > /tmp/mynewfile.txt        
两种方法都能同样地起作用。既然我们谈到反斜杠扩展,那么现在是时候提一提了,为了指定文字\,您可以将它放入单引号中,或者也可以输入\\(它将被扩展为\)。        
    请注意双引号的作用和单引号很接近,而双引号还允许 bash 做一些有限的扩展。因此,当您确实想要把文字文本传给命令时,单引号是最好的选择。

(5)专用字符集合

  [:digit:]:任意数字,相当于0-9

  [:lower:]:任意小写字母

  [:upper:]:任意大写字母

  [:alpha:]:任意大小写字母

  [:alnum:]:任意数字或字母

  [:space:]:空格

  [:punct:]:标点符号

    注意:引用时,需要在加一层括号

2.正则表达式

1、什么是正则表达式?       
    正则表达式(也称为“regex”或“regexp”)是一种用来描述文本模式的特殊语法。在 Linux 系统上,正则表达式通常被用来查找文本的模式,以及对文本流执行“搜索-替换”操作以及其它功能。        
2、与 glob 的比较        
   当我们看到正则表达式时,您可能发现正则表达式的语法看起来与我们上一篇教程(请参阅本教程最后的“参考资料”一节中列出的“第 1 部分”)中研究的“文件名匹配替换”语法相类似。但是,不要让它欺骗您;它们的类似性只是表面的。虽然正则表达式和文件名匹配替换模式可能看上去相类似,但是它们是根本不同的两种类型。        
3、简单子串        
   记住那个警告,让我们看一下最基本的正则表达式,简单子串。为了这样做,我们要使用 grep,它是一个扫描文件内容来查找适合特定正则表达式的命令。grep 打印与正则表达式匹配的每一行,并忽略与之不匹配的每一行:        
$ grep bash /etc/passwd        
operator:x:11:0:operator:/root:/bin/bash        
root:x:0:0::/root:/bin/bash        
ftp:x:40:1::/home/ftp:/bin/bash        
在上面的命令中,grep 的第一个参数是一个正则表达式;第二个参数是一个文件名。grep 读取 /etc/passwd 中的每一行并对它应用简单子串正则表达式 bash 来查找匹配项。如果找到一个匹配项,那么 grep 打印出整行;否则,忽略该行。        
4、理解简单子串        
    一般来说,如果您正在搜索一个子串,那么您可以不提供任何“特殊”字符,而只是逐字地指定文本。只有在子串包含 +、.、*、[、] 或 /(在这样的情况下,这些字符需要用引号括起来并在它们的前面使用反斜杠)才需要做特殊的事情。下面是简单子串正则表达式几个其它示例:        
   tmp (扫描查找文字串 tmp)        
 “\[box\]”(扫描查找文字串 [box])        
 “\*funny\*”(扫描查找文字串 *funny*)        
 “ld\.so”(扫描查找文字串 ld.so)        
5、元字符        
    使用正则表达式,可以利用元字符来执行比我们至今已研究过的示例复杂得多的搜索。这些元字符中的一个是 .(点),它与任何单个字符匹配:        
$ grep dev.hda /etc/fstab        
/dev/hda3 reiserfs noatime,ro 1 1        
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2        
/dev/hda2 swap sw 0 0        
#/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1        
    在本示例中,文字文本 dev.hda 没有出现在 /etc/fstab 中的任何一行中。但是,grep 扫描这些行时没有查找文字 dev.hda 字符串,而是查找 dev.hda 模式。请记住 . 将与任何单个字符相匹配。正如您看到的,. 元字符在功能上等价于 glob 扩展中 ? 元字符的工作原理。        
6、使用 []        
   如果我们希望与比 . 更具体一点地来匹配字符,那么我们可以使用 [ 和 ](方括号)来指定要匹配的字符子集:        
$ grep dev.hda[12] /etc/fstab        
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2        
/dev/hda2 swap swap sw 0 0  

 [\u4e00-\u9fa5] : 表示任意一个汉字 
 正如您看到的,这个特殊语法的作用与“glob”文件名扩展中的 [] 相同。        
7、使用 [^]        
    通过使 [ 后面紧跟一个 ^,您可以使方括号中的意思相反。在本例中,方括号将与未列在方括号内的任意字符匹配。同样,请注意我们在正则表达式中使用 [^] ,而在 glob 中使用 [!] :        
$ grep dev.hda[^12] /etc/fstab        
/dev/hda3 reiserfs noatime,ro 1 1        
/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1        
8、区别语法        
    注意下面一点很重要:方括号内部的语法根本不同于正则表达式其它部分中的语法。例如,如果在方括号内放置一个 . ,那么它允许方括号与文字 . 匹配,就象上面示例中的 1 和 2。比较起来,除非有\ 作为前缀,否则方括号外面的文字 . 被解释为一个元字符。通过输入如下命令,我们可以利用这一事实来打印 /etc/fstab 中包含文字串 dev.hda 的所有行的列表:        
$ grep dev[.]hda /etc/fstab        
或者,我们也可以输入:        
$ grep "dev\.hda" /etc/fstab        
这两个正则表达式都不可能与您的 /etc/fstab 文件中的任何行相匹配。        
9、“*”元字符        
    某些元字符本身不匹配任何字符,但却修改前一个字符的含义。一个这样的元字符是 * (星号),它用来与前一个字符的零次或者多次重复出现相匹配。这里是一些示例:        
 ab*c(与 abbbbc 匹配但不与 abqc 匹配)        
 ab*c(与 abc 匹配但不与 abbqbbc 匹配)        
 ab*c(与 ac 匹配但不与 cba 匹配)        
 b[cq]*e(与 bqe 匹配但不与 eb 匹配)        
 b[cq]*e(与 bccqqe 匹配但不与 bccc 匹配)        
 b[cq]*e(与 bqqcce 匹配但不与 cqe 匹配)        
 b[cq]*e(与 bbbeee 匹配)        
 .*(与任何字符串匹配)        
 foo.*(与以 foo 开始的任何字符串相匹配)        
 ac 行与正则表达式 ab*c 相匹配,因为星号也允许前面的表达式(b)出现零次。请注意解释 * 正则表达式元字符所用的方法与解释 * glob 字符的方法根本不同。        
10、行的开始和结束        

    我们在这里要详细描述的最后几个元字符是 ^ 和 $ 元字符,它们用来分别与行的开始和结束相匹配。通过在正则表达式开始处使用一个 ^ ,您可以将您的模式“锚定”在行的开始。在下面的示例中,我们使用 ^# 正则表达式来与以 # 字符开始的任何行相匹配:        
$ grep ^# /etc/fstab        
# /etc/fstab: static file system information.        
#        
11、完整行正则表达式        
    可以组合 ^ 和 $ 来与完整的行相匹配。例如,下面的正则表达式将与以 # 字符开始并以 . 字符结束的行相匹配,在其中间可以有任意多个其它字符:        
$ grep '^#.*/.$' /etc/fstab        
# /etc/fstab: static file system information.        
在上面的示例中,我们用单引号将我们的正则表达式括起来以阻止 shell 解释 $ 。在不使用单引号的情况下,grep 甚至没有机会查看 $,$ 就从我们的正则表达式上消失了。

正则总结(转)

元字符        
    .     :
小数点可以匹配除“\n”以外的任意一个字符。如果要匹配包括“\n”在内的所有字符,一般用[\s\S],或者是用“.”加(?s)匹配模式来实现。        
    [abc] :匹配方括号中的任意一个字符。可以使用-表示字符范围,如[a-z0-9]匹配小写字母和阿拉伯数字。        
    [^abc] :在方括号内开头使用^符号,表示匹配除方括号中字符之外的任意字符。       |    : 表示或 
\d 匹配阿拉伯数字,等同于[0-9]。        
\D 匹配阿拉伯数字之外的任意字符,等同于[^0-9]。        
\x 匹配十六进制数字,等同于[0-9A-Fa-f]。        
\X 匹配十六进制数字,等同于[^0-9A-Fa-f]。        
\w 匹配单词字母,等同于[0-9A-Za-z_]。        
\W 匹配单词字母之外的任意字符,等同于[^0-9A-Za-z_]。        
\t 匹配<TAB>字符。        
\s 匹配空白字符,等同于[ /t]。        
\S 匹配非空白字符,等同于[^ /t]。        
\a 所有的字母字符. 等同于[a-zA-Z]        
\l 小写字母 [a-z]        
\L 非小写字母 [^a-z]        
\u 大写字母 [A-Z]        
\U 非大写字母 [^A-Z]        

表示数量的元字符

        
元字符         说明        
*              匹配0-任意个        
\+             匹配1-任意个        
\?             匹配0-1个        
\{n,m\}        匹配n-m个        
\{n\}          匹配n个        
\{n,\}         匹配n-任意个        
\{,m\}         匹配0-m个        

换行符         说明

\r,\n          回车和换行

\\             匹配‘\’

\^,\$,\.       匹配“^”“$”“.”    

以下字符在匹配其本身时,通常需要进行转义。在实际应用中,根据具体情况,需要转义的字符可能不止如下所列字符 : $  ^  {  [  (  |  )  *  +  ?  \  
表示位置的符号    
$   匹配行尾     
^   匹配行首      
\<  匹配单词词首      
\>  匹配单词词尾  
   
\b  匹配单词边界 
 

      

   
    
   

原创文章,作者:血刀老祖,如若转载,请注明出处:http://www.178linux.com/11356

评论列表(1条)

  • stanley
    stanley 2016-02-28 12:20

    写的不错,你将拥有自主发布文章的权限,相信会一如既往的好