linux文件名匹配——通配符使用
背景:在linux使用过程中,经常需要查找文件,对命令中的通配符pattern和正则表达式的区分不是很清楚。有必要好好研究一下。
1 扫盲
1.1 通配符和正则表达式
当在使用命令行时,有很多时间都用来查找你所需要的文件,如ls find等。 S h e l l提供了一套完整的字符串模式匹配规则,或者称之为元字符,当s h e l l遇到上述字符时,就会把它们当作特殊字符,而不是文件名中的普通字符,这样用户就可以用它们来匹配相应的文件名,我理解这可以称为通配符。
通配符与正则表达式是有区别的,简单来说:通配符是用来通配的,正则表达式是用来匹配字符串的;
在文本过滤工具里,都是用正则表达式,比如像awk,sed,等,是针对文件的内容的。
而通配符多用在文件名上,比如查找find,ls,cp,等等。
其次,shell对通配符与正则表达式的处理也有不同,“ ”内一般为通配符(是shell本身提取处理),‘ ’内一般为正则表达式(shell会将其中的数据传递给其它命令处理)。
2 通配符详细介绍
测试数据
touch a a6.log abc.log ac.txt b c c5.txt x.log A
“*”
代表任意多个字符
例:查询以".log"结尾的文件 ll *.log
“?”
代表任意单个字符
例:只查询a、b、c ll ?
“[]”
代表“[”和“]”之间的某一个字符,比如[0-9]可以代表0-9之间的任意一个数字,[a-zA-Z]可以代表a-z和A-Z之间的任意一个字母,字母区分大小写。
例:只查询字母文件 ll [a-zA-Z]
例:查询以“.log”结尾且“.log”前只有两个字符的文件且第二个字符是数字 ll ?[0-9].log
“^”
表示匹配结果取反的意思,注意这个通配符必须要在[]中使用
例:查询不是以“.txt”结尾的文件 ll *[^txt]*
“{}”
表示符合括号内包含的多个文件
例:查询‘.log’和“.txt”结尾的文件 ll {*.log,*.txt}
注意: “.”这个符合比较特殊,如果匹配的条件加上了该符合那么说明查询结果文件就包含带“.”的文件
例如前面的“^”的例子,如果我这样查询“ll *.[^txt]*”,那么结果就不一样了
删除操作
例如:删除a、b、c和以.txt结尾的文件 rm -f {[abc],*.txt}
当然既然可以查询当然也可以使用通配符匹配的方式进行移动文件,如果需要在存在很多文件的文件夹中移动某些类型的文件那么使用通配符匹配的效率就显而易见了;当时通配符的使用技巧不单单只有这些,有空的可以多去研究。
3 实例
* 匹配文件名中的任何字符串,包括空字符串。 ? 匹配文件名中的任何单个字符。 [...] 匹配[ ]中所包含的任何字符。 [!...] 匹配[ ]中非感叹号!之后的字符。和^的效果一样
如:
5* 5开头的所有字符串
*5 5结尾的所有字符串
*5? 以5为倒数第二个字符的字符串
[0-9] 所有以数字的字符
[1,2] 1或者2
[!0-9] 不是数字的字符
ls /etc/[!a-n]*.conf 列出/etc/目录中不是以字母a到n开头的,并且以.conf结尾的文件
ls /etc/[a-n]*.conf 列出/etc/目录中以字母a到n开头的,并且以.conf结尾的文件
ls /bin/[ck]* 列出以 c或k开头的文件名