本文共 3774 字,大约阅读时间需要 12 分钟。
在 Perl 中处理文件是开发中常见的操作之一。本节将介绍几种常用的读取文件方法,以及文件路径处理的技巧。
以下是一个简单的读取文件并将内容一次性加载到数组中的方法:
$fdr = open("<$file") or die $!; # 打开文件@lines = <$fdr>; # 读取所有内容到数组close($fdr); # 释放资源
这种方法适用于逐行处理文件时不需要显式循环的情况。
如果需要对每一行进行处理,可以使用 while
循环:
$fdr = open("<$file") or die $!;while (<$fdr>) { # 处理当前行 my $line = $_; # 可以根据需要进行修改或输出 say $line;}close($fdr);
这种方法适合需要对每一行单独处理的场景。
要读取特定路径下的所有文件,可以使用 readdir
函数结合 glob
来获取文件列表:
my $dir = "/bld/xyz/toolgeneric/328";@files = glob("$dir/*/*");
这里,glob
函数会返回匹配路径下的所有文件。
如果需要删除一些旧文件或文件夹,可以参考以下脚本。脚本会检查文件的创建时间,删除超过一年前的文件。
#!/opt/exp/bin/perl -wuse File::Path;my $subdir = "/home/coolclf/rje/apaloads";@files = glob("$subdir/*");foreach my $file (@files) { my $mtime = (stat($file))[9]; # 获取文件创建时间 my @t = localtime($mtime); my $date = sprintf("%02u/%02u/%02u %02u:%02u:%02u", $t[4] + 1, $t[3], $t[5] % 100, $t[2], $t[1], $t[0]); print "$date\n"; if ($t[5] % 100 < 13) { print "line15: $file\n"; rmtree($file); # 删除文件夹 }}
以下是一个递归遍历路径的示例,能够深入访问文件夹中的所有文件和子文件夹:
#!/opt/exp/bin/perl -wuse strict;use warnings;sub lsr { my $cwd = shift; # 获取当前工作目录 local *DH; # 定义一个目录句柄 if (!opendir(DH, $cwd)) { warn "无法打开目录 $cwd: $! $^E"; return; } foreach (readdir(DH)) { next if $_ eq '.' || $_ eq '..'; # 跳过当前目录和上级目录 my $file = $cwd . '/' . $_; if (!-l $file && -d $_) { $file .= '/'; # 确保是路径 lsr($file); # 递归处理子文件夹 } # 可以在这里处理文件或文件夹 process($file, $cwd); } closedir(DH);}my ($size, $dircnt, $filecnt) = (0, 0, 0);sub process($$) { my $file = shift; # 接收文件路径 if (substr($file, -1, 1) eq '/') { $dircnt++; } else { $filecnt++; $size += -s $file; # 计算文件大小 }}lsr('.'); # 从当前目录开始递归print "总共有 $filecnt 个文件,$dircnt 个目录,总大小 $size 字节。\n";
在 Perl 中,处理输入输出时,通常会使用不同的方式来读取和写入文件。为了避免数据丢失或覆写,建议分别使用不同的文件句柄。例如:
open(my $fh, '<', '1-2.txt') or die $!; # 读取文件open(my $fw, '>', 'output.txt') or die $!; # 写入文件while ($line = <$fh>) { print $fw $line;}close($fh);close($fw);
这种方式避免了读写同一文件可能出现的数据丢失问题。
如果需要从命令行读取参数,可以使用 ARGV
变量来获取:
my $file = $ARGV[0]; # 获取第一个命令行参数open(my $fh, '<', $file) or die $!;while ($line = <$fh>) { # 处理每一行 if ($line =~ /^bjmcl0(\d\d)/) { if ($1 >= 33 && $1 <= 63) { $line = "#$line"; } } say $line;}
以下是一个遍历子目录文件的示例:
#!/opt/exp/bin/perl -wmy $dir = "/bld/xyz/toolgeneric/328";@files = glob("$dir/*/*");foreach my $file (@files) { print "line10: $file\n"; open(my $fh, $file) or next; while ($line = <$fh>) { if ($line =~ /xyz/) { print "xyz line17: $file: $line\n"; } } close($fh);}
以下是一个使用 $^I
变量的示例,用于在读写同一文件时临时备份文件:
#!/usr/bin/perl -wuse strict;$^I = '.bak'; # 设置备份扩展名while (<$ARGV>) { s/felixzh1//g; print;}
以下是一个统计当前目录中文件、子目录和总大小的示例:
#!/opt/exp/bin/perl -wuse strict;use warnings;sub lsr { my $cwd = shift; local *DH; if (!opendir(DH, $cwd)) { warn "无法打开目录 $cwd: $! $^E"; return; } $size = 0; $dircnt = 0; $filecnt = 0; foreach (readdir(DH)) { next if $_ eq '.' || $_ eq '..'; my $file = $cwd . '/' . $_; if (!-l $file && -d $_) { $file .= '/'; # 确保是路径 lsr($file, $cwd); } process($file, $cwd); } closedir(DH);}my ($size, $dircnt, $filecnt) = (0, 0, 0);sub process($$) { my $file = shift; if (substr($file, -1, 1) eq '/') { $dircnt++; } else { $filecnt++; $size += -s $file; }}lsr('.');print "$filecnt 文件,$dircnt 目录,总大小 $size 字节。\n";
以上是一些常用的 Perl 文件操作示例,涵盖了读取、写入、删除、路径遍历等功能。通过合理组合这些操作,可以应对各种文件处理需求。
转载地址:http://qwfx.baihongyu.com/