Как я могу проверить расширение файла, используя Perl?
в мой скрипт perl файл передается как аргумент. Файл может быть или содержащий .
Я хочу написать код, который выглядит примерно так
if ($file is a zip) {
unzip $file
$file =~ s/zip$/txt/;
}
один из способов проверить расширение - сделать разделение на .
а затем сопоставьте последний результат в массиве (возвращаемый split).
есть ли лучший способ?
6 ответов
для этого можно использовать 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
запуск этого дает:
$ ./files
file.txt is a text file
file.zip is a zip file
file.pl is an unknown file type
другое решение-использовать File::Type
который определяет тип двоичного файла.
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
}
таким образом, вам не придется иметь дело с отсутствующей или неправильной расширения.
Как насчет проверки конца имени файла?
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();
}
дополнительная информация здесь.
вы можете проверить расширение файла с помощью regex match как:
if($file =~ /\.zip$/i) {
# $file is a zip file
}
зачем полагаться на расширение? Просто попробуйте распаковать и использовать соответствующую обработку исключений:
eval {
# try to unzip the file
};
if ($@) {
# not a zip file
}
Я знаю, что этому вопросу несколько лет, но для тех, кто приходит сюда в будущем, простой способ разбить путь к файлу на его составной путь, имя файла, базовое имя и расширение заключается в следующем.
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";
}
надеюсь, что это помогает.