加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

通配符和正则表达式

发布时间:2020-12-13 22:24:24 所属栏目:百科 来源:网络整理
导读:第一次觉得Linux的强大是因为接触到了grep这个命令,然后写的大多数脚本都用到了管道+grep,后来又接触到了awk和sed,才知道强大的不是命令而是正则表达式。 后来发现当我要查找某个文件时用到了find,然后从百度上找到了一些文件名匹配的方式,我以为我依然

第一次觉得Linux的强大是因为接触到了grep这个命令,然后写的大多数脚本都用到了管道+grep,后来又接触到了awk和sed,才知道强大的不是命令而是正则表达式。

后来发现当我要查找某个文件时用到了find,然后从百度上找到了一些文件名匹配的方式,我以为我依然使用的是正则,直到后来看了鸟叔才知道这个使用的是通配符,而且他也一再强调一定要把正则和通配符分开,所以今天写一篇关于正则表达式和通配符的文章。

个人理解:通配符是对文件操作;正则表达式是对字符串的匹配--》在Linux中


1.)通配符--》顾名思义,满足条件的通通匹配

Linux中包含了如下通配符

1.1)*--》匹配任一多个字符(包含0个)

举例如下:

<如果想查找home目录下的一个文件,只记得这个文件名中包含file>执行如下命令即可

find /home -name*file*则可以匹配 file afile aafile fileb filebb afileb afilebb ...

<如果想删除/home/test目录下的所有文件>执行如下命令即可

rm -f /home/test/*如果子目录也要删除则执行 rm -rf /home/test/*

建议使用*来批量删除文件前最后按两次tab,这样控制台会打印出所有你想删的文件,确保好了再删除,毕竟删除后想找回来还是很麻烦的。


1.2)?--》匹配任意的一个字符

/tmp/目录下有a b c aaab ac bb cc aaa aab bbb ccc文件,

<如果想删除单个字符的文件>

rm -f ?

<如果想删除aa ab ac这些文件>

rm -f a? //思考,a会被删除吗???


1.3)[] --》匹配括号内的字符

/tmp/目录下有a b c aaab ac bb cc aaa aababb acb adbccc文件,

<如果想删除aab abb acb这两个文件>

rm -f a[abc]b

<如果想删除aab abb acb adb>

rm -f a[a-d]b or rm -f a?b //思考 rm -f a*b可以吗???

<如果想把/tmp/aaa文件中小写字母全部转换为大写>

cat /tmp/aaa| tr [a-z] [A-Z]


1.4) [!] --》不匹配括号内的字符

/tmp/目录下有a b c aaab ac bb cc aaa aababb acb adbccc文件,

<如果想得到不是以a开头的所有文件(b c bb cc ccc)>

ls [!a]*


1.5) 举个错误的例子

/tmp目录有file1 file2 file3 file4tmpfile文件

#cat /tmp/tmpfile //控制台中输入命令,下面的是结果

aba

abb

abc

# cat /tmp/tmpfile | grep ab[a-z] //输出和想的相同

aba

abb

abc

// 如果此时我执行如下命令

# touch abd; cat /tmp/tmpfile | grep ab[a-z] //输出确为空,想想为什么???后面会揭晓答案。

// 然后执行如下命令

# echo ab? >> /tmp/tmpfile; cat /tmp/tmpfile | grep ab[a-z]

abd //结果是否和你预期的一样,思考一下,你就会知道之前为什么输出空了。

// 因为执行grep ab[a-z]的时候,Linux首先会匹配通配符,所以对于为空的指令是因为Linux中执行的命令是

#cat /tmp/tmpfile | grep abd //所以输出为空,通过echo ab? >> /tmp/tmpfile后查看文件内容可以看到文件尾部插入了adb,所以正确的翻译是echo abd >> /tmp/tmpfile

*** 修改方式:cat /tmp/tmpfile | grep ab[a-z];则通配符匹配的过滤后执行 cat /tmp/tempfile | grep ab[a-z],然后正则匹配的时候得到想要的结果

// 而开始不为空是因为Linux匹配通配符的时候没有匹配到所以执行了

#cat /tmp/tmpfile | grep[a-z];然后作为正则表达式匹配的时候找到了aba abb abc.

*** 修改方式: cat /tmp/tmpfile | grep "ab[a-z]",直接当做正则来匹配

//bash对于通配符相关的字符进行了特别的处理,所以包含这些参数的命令需要非常小心,尽量使用来转义。



2)正则表达式 --》顾名思义,按正经的规则表达式来匹配

正则表达式是字符和元字符的集合,其中的一些概念如下


2,1)字符集

可以理解为普通的字符,空格也算


2.2)锚

可以理解为固定的位置,很形象。^, $,&;, &;.

其中^表示行首,$表示行尾,&;表示单词开始的字符,&;表示单词结尾的字符

<如果想匹配以a开始以b结束的行>

grep "^a" | grep "b$"或者 grep "^a.*b$" //这里的|不是或的意思,是管道

<如果想匹配包含以f开头k结尾的单词的行>

grep "&;f" | grep "b&;"或者grep "&;f.*k&;"


2.3)元字符

2.3.1) * --》匹配前一个字符零次或任意多次(注意,必须和前一个字符比较。注意和通配符的区别)

grep "a*" /tmp/tmpfile--》输出tmpfile的所有内容(注意是匹配a零次或多次,因为所以行都可以匹配"",即0次a)

grep "aa*" /tmp/tmpfile --》输出tmpfile中包含a或者aa或者aaa或者aaaa...的行(至少包含一个a,其实可以匹配aa则一定可以被a匹配)

grep "aaa*" /tmp/tmpfile--》输出tmpfile中包含aa或者aaa...的行


2.3.2)+--》匹配前一个字符任意多次(不包含0次,与*的唯一差别)

grep "a+" /tmp/tmpfile--》输出结果等同 grep aa* /tmp/tmpfile

grep "aa+" /tmpfile --》输出结果等同 grep aaa* /tmp/tmpfile


2.3.3).--》匹配任意字符一次,但不能匹配换行符

grep "a. /tmp/tempfile --》与grep aa* /tmp/tmpfile的唯一区别是不能匹配仅有一个a,且这个a在结尾(即a的下一个字符是换行)


2.3.4) []匹配属于集合中的任意一个字符

grep“[a-z]” /tmp/tempfile --》匹配文件中包含字母的行


2.3.5)[^]匹配不属于集合中的任意字符

grep“[^a-z]” /tmp/tmpfile--》匹配不包含字母的行


2.3.6){m}匹配前一个字母m次(m为指定数字)

grep“a{3}”/tmp/tmpfile --》匹配包含aaa的行


2.3.7){m,}匹配前一个字符至少m次


2.3.8){m,n}匹配前一个字符最少m次,最多n次


正则表达式很复杂,需要反复的锻炼才行,建议与VIM的学习结合起来。


// 简单的例子

1. /tmp下有aaa bbc dde 三个文件, 想grep出aaa bbc文件

# ls | grep -v dde // 如果/tmp下还有其他文件就失效了, 很明显这种想法是不可取

# ls | grep "aaa|bbc" // grep的或实现

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读