Perl 目录
Perl - 处理目录
Section titled “Perl - 处理目录”Perl 提供了内置函数,用于与文件系统的目录结构交互。这些函数允许你列出目录内容、创建、删除和更改目录。
核心目录函数:
opendir(my $dh, $dirname) or die "Cannot open directory '$dirname': $!"; # 打开一个目录my @entries = readdir($dh); # 从目录读取条目rewinddir($dh); # 重置目录流的指针到开头telldir($dh); # 获取目录流中的当前位置seekdir($dh, $pos); # 设置目录流中的位置closedir($dh); # 关闭目录句柄
mkdir($new_dir, $permissions) or die "Cannot create directory '$new_dir': $!"; # 创建一个目录rmdir($dir_to_remove) or die "Cannot remove directory '$dir_to_remove': $!"; # 删除一个空目录chdir($target_dir) or die "Cannot change to directory '$target_dir': $!"; # 更改当前目录始终在脚本中使用 use strict; 和 use warnings;。使用词法目录句柄 (lexical directory handles)(my $dh)以提高代码安全性。
列出目录内容
Section titled “列出目录内容”方法 1:使用 opendir 和 readdir
Section titled “方法 1:使用 opendir 和 readdir”这是列出目录内容的传统方法。
#!/usr/bin/perluse strict;use warnings;
my $dir_path = '.'; # 当前目录
opendir(my $dh, $dir_path) or die "Can't open $dir_path: $!";
print "Entries in '$dir_path':\n";while (my $entry = readdir($dh)) { # readdir 也返回 '.' 和 '..' next if $entry eq '.' or $entry eq '..'; print "$entry\n";}
closedir($dh);方法 2:使用 glob()
Section titled “方法 2:使用 glob()”glob() 函数(或 <*>)展开文件名模式,类似于 shell 的 globbing。
#!/usr/bin/perluse strict;use warnings;
my $dir_pattern = './*'; # 当前目录中的所有文件和目录
print "Entries matching '$dir_pattern' (via glob):\n";my @files = glob($dir_pattern);# 或者:my @files = <$dir_pattern>;
foreach my $file (@files) { print "$file\n";}
# 仅获取 /tmp 中的 .txt 文件:# my @text_files = glob('/tmp/*.txt');
# 获取 /tmp 中的隐藏文件(以 . 开头):# my @hidden_files = glob('/tmp/.*');glob() 对于简单模式很方便,但如果模式来自不受信任的输入,可能会有安全隐患。
过滤目录列表
Section titled “过滤目录列表”可以将 readdir 与 grep 结合使用来过滤条目。
#!/usr/bin/perluse strict;use warnings;
my $dir_path = '.';opendir(my $dh, $dir_path) or die "Can't open $dir_path: $!";
print "Perl files (.pl, .pm) in '$dir_path':\n";my @perl_files = grep { /\.(pl|pm)$/i && -f "$dir_path/$_" } readdir($dh);# -f 检查确保它是文件,而不是以 .pl 结尾的目录
closedir($dh);
foreach my $file (@perl_files) { print "$file\n";}mkdir() 函数创建一个新目录。可选的第二个参数指定权限(例如 0755)。
#!/usr/bin/perluse strict;use warnings;
my $new_dir = './my_new_directory';my $permissions = 0755; # 典型权限
if (mkdir($new_dir, $permissions)) { print "Directory '$new_dir' created successfully.\n"; # 为示例目的进行清理 rmdir($new_dir) or warn "Could not remove test directory '$new_dir': $!";} else { warn "Couldn't create directory '$new_dir': $!";}rmdir() 函数删除一个空目录。
#!/usr/bin/perluse strict;use warnings;
my $dir_to_remove = './empty_dir_to_remove';
# 首先为示例创建它mkdir($dir_to_remove, 0755) or die "Setup: Could not create $dir_to_remove: $!";
if (rmdir($dir_to_remove)) { print "Directory '$dir_to_remove' removed successfully.\n";} else { warn "Couldn't remove directory '$dir_to_remove': $!"; warn "(它是否为空?你是否有权限?)";}要删除一个包含内容的目录,需要先递归删除其内容。像 File::Path 这样的模块提供了 remove_tree 等函数来实现这一点。
更改当前目录
Section titled “更改当前目录”chdir() 函数更改脚本的当前工作目录。
#!/usr/bin/perluse strict;use warnings;use Cwd qw(getcwd);
my $target_dir = '/tmp'; # 示例目标目录
my $original_dir = getcwd(); # 获取当前工作目录print "Original directory: $original_dir\n";
if (chdir($target_dir)) { my $new_current_dir = getcwd(); print "Successfully changed to '$target_dir'. New current directory: $new_current_dir\n"; # 切回原始目录(如果需要,这是一个好习惯) chdir($original_dir) or warn "Could not change back to $original_dir: $!";} else { warn "Couldn't change to directory '$target_dir': $!";}现代替代方案
Section titled “现代替代方案”虽然 Perl 的内置函数功能强大,但对于更复杂或面向对象的文件和目录操作,可以考虑使用 CPAN 模块,例如:
Path::Tiny: 一个小巧、快速且方便的路径操作模块。Path::Class: 提供面向对象的文件和目录接口。File::Spec: 用于平台无关的路径操作(例如,拼接路径组件)。
这些模块通常能使代码更清晰、更健壮,特别是对于跨平台应用。