Как я могу проверить расширение файла с помощью Perl? - PullRequest
7 голосов
/ 15 октября 2010

На мой Perl-скрипт файл передается как аргумент. Файл может быть файлом .txt или .zip, содержащим файл .txt.

Я хочу написать код, который будет выглядеть примерно так

if ($file is a zip) {

    unzip $file
    $file =~ s/zip$/txt/;
}

Один из способов проверить расширение - это выполнить разбиение на ., а затем сопоставить последний результат в массиве (возвращаемый функцией split).

Есть какой-нибудь лучший способ?

Ответы [ 6 ]

12 голосов
/ 15 октября 2010

Другое решение состоит в использовании 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
}

Таким образом, вам не нужно иметь дело с отсутствующими / неправильными расширениями.

11 голосов
/ 15 октября 2010

Для этого вы можете использовать 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
7 голосов
/ 15 октября 2010

Как насчет проверки конца имени файла?

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();
}

больше информации здесь .

3 голосов
/ 04 апреля 2014

Я знаю, что этому вопросу уже несколько лет, но для любого, кто придет сюда в будущем, простой способ разбить путь к файлу на составляющий путь, имя файла, базовое имя и расширение выглядит следующим образом.

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";
}

Надеюсь, это поможет.

3 голосов
/ 15 октября 2010

Вы можете проверить расширение файла с помощью соответствия регулярному выражению как:

if($file =~ /\.zip$/i) {
        # $file is a zip file 
}
2 голосов
/ 15 октября 2010

Зачем полагаться на расширение файла? Просто попробуйте распаковать и использовать соответствующую обработку исключений:

eval {
    # try to unzip the file
};

if ($@) {
    # not a zip file
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...