2010-10-15 18 views
7

Perl betiğimde bir dosya bir argüman olarak geçiyor. Dosya, .txt dosya veya .txt dosyasını içeren bir .zip dosya olabilir.Perl kullanarak bir dosyanın uzantısını nasıl kontrol edebilirim?

Ben . üzerinde bir bölünme yapmak ve sonra da (bölünmüş tarafından döndürülen) dizideki Son sonucu maç etmektir uzantısını kontrol etmek için bu

if ($file is a zip) { 

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

Tek yol gibi görünür kod yazmak istiyorum.

Daha iyi bir yolu var mı?

+8

Sadece uzantıyı kontrol etmek istediğinizden emin misiniz? Eğer ne tür bir dosya ile uğraştığınızı test etmeyi umuyorsanız, mim tipini kontrol etmekten daha iyi olur. Şunun gibi bir şeye bakın: http://search.cpan.org/~pmison/File-Type-0.22/lib/File/Type.pm – totels

+0

@ totels desteği ve birkaç alt yanıtın bir çiftiyle destekleme . Uzatma üzerinde güvenme (ya) mv virus.exe hooters.jpg') ya da sağlam ('mv biraz büyük-dossy-garbage.bin whatever.zip') güveniyor düşünüyorum şaşırıyorum. Zip ve yakalama hataları veya MIME türünü incelemek, verilen doğru cevaplardır. Uzantıyı kullanan herhangi bir çözüm bir hatadır. – Ashley

cevap

11

Bunun için File :: Basename dosyasını kullanabilirsiniz.

#!/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 

Running bu verir:

$ ./files 
file.txt is a text file 
file.zip is a zip file 
file.pl is an unknown file type 
+0

'fileparse', önce dizin adını değil, dosya adını döndürür. –

+0

Haklısın elbette, ve ben düzeltdim. Beş yıldan fazla fark edilmeden garipleşti. İşaret ettiğin için teşekkürler. –

+0

Endişeye gerek yok, siparişinizi düzenledikten sonra yazıcınız sorunumu çözdü :) –

6

Dosya adının sonuna bakmaya ne dersin?

if ($file =~ /\.zip$/i) { 

ve sonra:

use strict; 
use Archive::Extract; 

if ($file =~ /\.zip$/i) { 
    my $ae = Archive::Extract->new(archive => $file); 
    my $ok = $ae->extract(); 
    my $files = $ae->files(); 
} 

fazla bilgi here.

if($file =~ /\.zip$/i) { 
     # $file is a zip file 
} 
2

Sen olarak regex maç kullanarak dosya uzantısını kontrol edebilir? Sadece uygun durum işleme halletmek ve kullanmayı deneyin:

eval { 
    # try to unzip the file 
}; 

if ([email protected]) { 
    # not a zip file 
} 
2

Neden dosya uzantısı dayanmaktadır:

+0

Sisteminizde 'unzip' yüklü değilse veya yolunuzda değilse ne olur? –

+0

@Prakash: 'unzip'in perl işlevi olması gerekiyor.Nevermind, yorumlarla değiştirildi :) –

12

Başka bir çözüm ikili dosya türünü belirler File::Type kullanımını sağlamaktır.

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 
} 

Bu şekilde, eksik/yanlış uzantılarla uğraşmanız gerekmez.

+1

+1, ancak benim $ file_type = File :: Type-> mime_type ($ file); '' $ dosya_type = $ ft-> mime_type ($ file); – Toto

+0

Bunu işaretlediğiniz için teşekkürler. –

+2

'Dosya :: Tür' burada çalışır, ancak genel olarak ['File :: LibMagic'] (http://p3rl.org/File::LibMagic) ile karşılaştırıldığında oldukça berbat bir iş yapar. – daxim

1

Bu soru birkaç yıllık biliyorum ama gelecekte burada geliyor herkes için, kolay bir yol kendisini oluşturan yoluna ayrı bir dosya yolu kırmak için , dosya adı, basename ve uzantı aşağıdaki gibidir.

use File::Basename; 

my $filepath = '/foo/bar.txt'; 

my ($basename, $parentdir, $extension) = fileparse($filepath, qr/\.[^.]*$/); 
my $filename = $basename . $extension; 

Bu sonuçları aşağıdakilerle test edebilirsiniz.

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

Bu yardımcı olur umarım.

İlgili konular