Perl文件名通配和文件查找
在shell中使用*
来对文件名进行通配扩展,在Perl中也同样支持文件名通配。而且perl中的glob通配方式和shell的通配方式完全一致,实际上perl的glob函数就是直接调用csh来通配的(如果不存在csh,则使用其它shell),也因此通配是一个效率较低的操作。
glob通配函数
1 | 元字符 意义 |
注意:
[]
支持[0-9] [a-z] [A-Z] [A-z]
类似的范围通配,其中[A-z]
等价于[A-Za-z]
- 不支持
[^]
取反 - 特别需要注意的是
[1-34]
通配的是[1234]
,而不是1到34,因为中括号只能匹配单个字符
例如:
1 | use 5.010; |
在glob函数中,空格具有特殊含义,如果想要匹配包含空格的文件名,必须将其使用引号(单/双引号皆可)包围。
例如,要匹配hello world.log
文件:
1 | glob "'hello w*.log'"; |
File::Glob模块提供更丰富的通配规则,可以去查看下手册。不过说实话,用到的几乎应该不多。
尖括号<>通配写法
在glob出现之前,人们都使用尖括号表达式来通配。它和glob的实现是完全一致的,仅仅只是从尖括号改为了glob函数。
例如,匹配/root下的sh文件,下面两种写法完全等价:
1 | say </root/*.sh>; |
还可以使用变量替换:
1 | $dir="/etc"; |
同样,匹配包含空格的文件,可能需要使用引号包围:
1 | say <"hello w*.log">; |
在这里需要搞清楚尖括号内的到底会被解析成文件句柄还是解析成通配符。perl的解析规则是:假如尖括号内的内容满足标识符规则(文件句柄的名称要满足此规则),则会解析为文件句柄,否则解析成通配符。
以下是几种情况的区分示例:
1 | my @files = <FOO/*>; # 文件名通配 |
从第三行和第5行可以看出,当使用变量且只有变量名替换的时候,会优先解析为文件句柄。
文件查找:关于find2perl脚本
在unix下有一个find工具,用来查找文件非常方便。perl提供了一个find2perl的工具(该工具是在安装perl时自带的),它可以将find查找文件时的表达式转换成perl对应的查找语句。
find2perl的选项和用法和find的用法99%都一样,只有几项额外的是find2perl自身提供的,但这样的选项非常少。
注意,find2perl不是文件查找工具,而是将我们写的find命令表达式转换为等价的perl文件查找语句。
例如,搜索/etc目录下所有.cnf
结尾的文件,find命令的表达式如下:
1 | find /etc -type f -name "*.cnf" |
执行find2perl:
1 | [[email protected] perlapp]# find2perl /etc/ -type f -name "*.cnf" |
可以看出,上面生成了一个wanted子程序,以后要查找/etc/*.cnf
文件时,只需调用wanted子程序即可。例如:
1 | [[email protected] perlapp]# find2perl /etc/ -type f -name "*.cnf" >24.plx |