实际上perl文件和目录的操作可以分成两部分。
第一部分是文件和目录的简单操作,第二部分是文件属性的相关操作。
文件和目录的简单操作
这部分内容包括了文件和目录的创建、删除、移动、复制和搜索。
注意了,这里讲述的是是直接在perl命令中进行文件,不是在终端进行的,不要把shell和perl混了。
- 当前目录的获取
perl当中没有直接函数可以获取当前目录,可以通过加载Cwd函数获取当前目录
perl -M'Cwd' -e 'print cwd(),"\n"'
perl -M'Cwd' -e 'print getcwd(),"\n"'
此外,我们还可以显式指定文件或目录获取其绝对路径
perl -M'Cwd qw(abs_path)' -e 'print abs_path("dashbi"),"\n"
- 文件和目录的创建和删除
文件的创建可以通过open句柄打开相关文件进行创建。
文件的删除可以通过unlink函数进行操作,可以接单个元素也可以接列表操作。
目录创建通过mkdir进行操作。
perl -e 'mkdir "dashabi"'
目录的删除通过rmdir进行操作。
perl -e 'rmdir "dashabi"
但是实际上通过这种方式创建的目录和删除目录,只能清楚没有的目录,如果我想一次性迭代的创建多个目录,目录包含目录等。或者递归删除多个目录,那么这样的方式太过复杂。这个时候我们可以利用File::Path函数中mkpath和rmtree两个函数。
perl -M'File::Path qw(mkpath)' -e 'mkpath("dashabi/dashabi")'
perl -M'File::Path qw(rmtree)' -e 'rmtree("dashabi/dashabi")
- 文件和目录的复制和移动和重名命名
文件的复制和移动,可以通过File::Copy中的cp和mv函数,重命名可以利用perl自带的rename,如果想利用更高级的批量重命名的方式,可以利用File::Rename包的rename函数 - 文件的搜索
这里利用的是File::Find中的find命令。实际上find命令有两种用法,第二种用法实际是第一种用法的一个种情况。find命令实际用到了回调函数,即每找到一个文件,针对每个找到的文件一个子程序,只不过这个子程序以匿名子程序的方式传递给了find函数
● find用法一,find({哈希}, @dir_files)
哈希内容包括以下:
○ wanted=>sub{},wanted接一个匿名子程序,表示找到的每个文件执行什么操作。
○ preprocess=>sub{},preprocess接一个匿名子程序,表示在wanted之前,执行操作,比如对目录先进行排序等。
○ postprocess=>sub{},postprocess接一个匿名子程序,表示在wanted之后,执行什么操作。
○ no_chdir=>1表示不进入子程序,no_chdir=>0表示进行子程序,这两个的区别在于,如果设置之后File::Find::dir 和
File::Find::name是相对路径+文件名,
只有文件名。no_chdir=>1表示进入目录,
File::Find::dir是绝对路径,$是绝对路径+文件名。
○ bydepth是表示找到子目录先处理子目录文件再处理自身。
文件属性相关操作
这一部分包括对文件属性的检测,比如是否是文件,是否为目录,是否可读可写,是否可执行,文件的大小,上次访问的时间,上次修改的时间等;此外可以通过stat查看文件的属性,有很多相关属性,具体操作可以通过perldoc -f stat进行查看;此外可以通过chmod修改权限,chown UID, GID, LIST进行修改。还可通过utime()修改atime和mtime,但是ctime是系统自动维持的无法进行修改。
实际上,除了文件属性的检测外,其它的我们基本不会用到,你也不会闲得没事去修改文件的属组或属主,也很少去修改的文件的属性,那么你通过utime()修改atime和mtime又是干啥?小朋友,你有不良的目的哦。
image.png
这里举个例子,比如通过find函数找到的文件检测文件类型和文件大小等。
perl -M'File::Find' -e 'find(sub{if(-f $File::Find::name and (-s _) < 512) {push @files, $File::Find::name};foreach my $file(@files){print "$file\n"}}, qw(./))'
比如这个就是对当前目录中的文件进行搜索,找到是文件,并且文件大小<512的文件,添加到@files数组中,然后通过foreach打印出来。