如何使用Perl检查文件的扩展名?
对于我的perl脚本,一个文件作为参数传递。该文件可以是如何使用Perl检查文件的扩展名?,perl,file,Perl,File,对于我的perl脚本,一个文件作为参数传递。该文件可以是.txt文件,也可以是包含.txt文件的.zip文件 我想写类似这样的代码 if ($file is a zip) { unzip $file $file =~ s/zip$/txt/; } 检查扩展的一种方法是对执行拆分,然后匹配数组中的最后一个结果(由拆分返回) 有更好的方法吗?检查文件名的结尾怎么样 if ($file =~ /\.zip$/i) { 然后: use strict; use Archive::Ex
.txt
文件,也可以是包含.txt
文件的.zip
文件
我想写类似这样的代码
if ($file is a zip) {
unzip $file
$file =~ s/zip$/txt/;
}
检查扩展的一种方法是对
执行拆分,然后匹配数组中的最后一个结果(由拆分返回)
有更好的方法吗?检查文件名的结尾怎么样
if ($file =~ /\.zip$/i) {
然后:
use strict;
use Archive::Extract;
if ($file =~ /\.zip$/i) {
my $ae = Archive::Extract->new(archive => $file);
my $ok = $ae->extract();
my $files = $ae->files();
}
更多信息。您可以使用正则表达式匹配项检查文件扩展名,如下所示:
if($file =~ /\.zip$/i) {
# $file is a zip file
}
为什么要依赖文件扩展名?只需尝试解压缩并使用适当的异常处理:
eval {
# try to unzip the file
};
if ($@) {
# not a zip file
}
另一个解决方案是利用它来确定二进制文件的类型
use strict;
use warnings;
use File::Type;
my $file = '/path/to/file.ext';
my $ft = File::Type->new();
my $file_type = $ft->mime_type($file);
if ( $file_type eq 'application/octet-stream' ) {
# possibly a text file
}
elsif ( $file_type eq 'application/zip' ) {
# file is a zip archive
}
这样,您就不必处理丢失/错误的扩展名。您可以使用File::Basename进行处理
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use File::Basename;
my @exts = qw(.txt .zip);
while (my $file = <DATA>) {
chomp $file;
my ($name, $dir, $ext) = fileparse($file, @exts);
given ($ext) {
when ('.txt') {
say "$file is a text file";
}
when ('.zip') {
say "$file is a zip file";
}
default {
say "$file is an unknown file type";
}
}
}
__DATA__
file.txt
file.zip
file.pl
我知道这个问题已经问了好几年了,但对于将来来到这里的任何人来说,将文件路径分解为其组成路径、文件名、基名称和扩展名的简单方法如下
use File::Basename;
my $filepath = '/foo/bar.txt';
my ($basename, $parentdir, $extension) = fileparse($filepath, qr/\.[^.]*$/);
my $filename = $basename . $extension;
您可以使用以下内容测试它的结果
my @test_paths = (
'/foo/bar/fish.wibble',
'/foo/bar/fish.',
'/foo/bar/fish.asdf.d',
'/foo/bar/fish.wibble.',
'/fish.wibble',
'fish.wibble',
);
foreach my $this_path (@test_paths) {
print "Current path: $this_path\n";
my ($this_basename, $parentdir, $extension) = fileparse($this_path, qr/\.[^.]*$/);
my $this_filename = $this_basename . $extension;
foreach my $var (qw/$parentdir $this_filename $this_basename $extension/) {
print "$var = '" . eval($var) . "'\n";
}
print "\n\n";
}
希望这能有所帮助。可能有点晚,但可以作为替代参考:
sub unzip_all {
my $director = shift;
opendir my $DIRH, "$director" or die;
my @files = readdir $DIRH;
foreach my $file (@files){
my $type = `file $director/$file`;
if ($type =~ m/gzip compressed data/){
system "gunzip $director/$file";
}
}
close $DIRH;
return;
}
这里可以使用linux通过使用(``)从perl执行它。您可以传递文件夹的路径,并评估是否存在按
file
分类为gzip压缩的文件 您确定只想检查分机吗?如果您希望测试正在处理的文件类型,最好检查mime类型。看看下面这样的例子:支持@totels和一些较低的回答。我很惊讶有多少人认为依赖扩展是安全的(mv virus.exe hooters.jpg
)或健壮的(mv some-mage-dossy-garbage.bin whatever.zip
)。假设zip和捕捉错误或探索MIME类型是正确的答案。任何使用扩展名的解决方案都是错误的。+1,但是您应该替换my$file\u type=file::type->mime\u type($file)代码>按my$file\u type=$ft->mime\u type($file)
File::Type
在这里工作,但与之相比,通常做的工作相当糟糕。这可能是最好的方法(无论是哪个模块),但是-T File测试操作符可能也值得一看。daxim:我将尝试File::LibMagic
。谢谢。如果您的系统上没有安装“unzip”,或者它不在您的路径中,该怎么办?@Prakash:unzip
应该是一个perl函数。没关系,替换为注释:)fileparse
首先返回文件名,而不是目录。当然,你是对的,我已经修复了它。奇怪的是,五年多以来它都没有被注意到。谢谢你指出。不用担心,你的帖子在我整理好订单后解决了我的问题:)
sub unzip_all {
my $director = shift;
opendir my $DIRH, "$director" or die;
my @files = readdir $DIRH;
foreach my $file (@files){
my $type = `file $director/$file`;
if ($type =~ m/gzip compressed data/){
system "gunzip $director/$file";
}
}
close $DIRH;
return;
}