通配符和正则表达式
来源:互联网 发布:sql server insert语句 编辑:程序博客网 时间:2024/05/17 06:41
第一次觉得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 aa ab ac bb cc aaa aab bbb ccc文件,
<如果想删除单个字符的文件>
rm -f ?
<如果想删除aa ab ac这些文件>
rm -f a? // 思考,a会被删除吗???
1.3) [] --》 匹配括号内的字符
/tmp/目录下有a b c aa ab ac bb cc aaa aab abb acb adb ccc文件,
<如果想删除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 aa ab ac bb cc aaa aab abb acb adb ccc文件,
<如果想得到不是以a开头的所有文件(b c bb cc ccc)>
ls [!a]*
1.5) 举个错误的例子
/tmp目录有file1 file2 file3 file4 tmpfile文件
# 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的或实现
- 通配符和正则表达式
- 正则表达式 和 通配符
- 通配符和正则表达式
- 正则表达式和通配符
- 通配符和正则表达式
- 通配符和正则表达式
- bash通配符和正则表达式
- Shell通配符和正则表达式
- linux通配符和正则表达式
- linux通配符和正则表达式
- linux 正则表达式和通配符
- 通配符和正则表达式联系和区别
- 将通配符*和?处理成正则表达式
- 通配符和正则表达式的区别
- 正则表达式和通配符的区别
- 通配符和正则表达式的区别
- 正则表达式和通配符的区别
- 正则表达式和通配符的区别
- [推荐系统]mahout中实现的几种相似度计算方法
- 《Objective-C基础教程》第11章 属性
- i = i++为什么会是i原来的值??
- OpenCV进阶之路:神经网络识别车牌字符
- [2015-08-13] python023
- 通配符和正则表达式
- iOS 审核加急 可以用中文了 。。
- Unity 翻书效果
- HDOJ2041 超级楼梯(dp & 打表)
- HDU 1124 Factorial(数论)
- NZND壳-第二天
- 移动端视频通话软件
- ViewPager的PagerAdapter.notifyDataSetChanged()
- 在控件的任意位置显示图片