2008-08-22 24 views
30

किसी दिए गए निर्देशिका की सामग्री को सरणी में पढ़ने के लिए मैं पर्ल कैसे प्राप्त करूं?पर्ल में निर्देशिका की सामग्री में मैं कैसे पढ़ूं?

Backticks ऐसा कर सकता है, लेकिन क्या 'स्कैंडर' या इसी तरह की अवधि का उपयोग करके कुछ विधि है?

उत्तर

45
opendir(D, "/path/to/directory") || die "Can't open directory: $!\n"; 
while (my $f = readdir(D)) { 
    print "\$f = $f\n"; 
} 
closedir(D); 

संपादित करें: ओह, माफ करना, याद किया "एक सरणी में" भाग:

my $d = shift; 

opendir(D, "$d") || die "Can't open directory $d: $!\n"; 
my @list = readdir(D); 
closedir(D); 

foreach my $f (@list) { 
    print "\$f = $f\n"; 
} 

EDIT2: अन्य उत्तर के अधिकांश वैध हैं, लेकिन मैं विशेष रूप से this answer पर टिप्पणी करना चाहता था, जिसमें इस समाधान की पेशकश की है:

opendir(DIR, $somedir) || die "Can't open directory $somedir: $!"; 
@dots = grep { (!/^\./) && -f "$somedir/$_" } readdir(DIR); 
closedir DIR; 

पहले, दस्तावेज़ के लिए के बाद से पोस्टर नहीं था क्या यह कर रहा है: यह एक grep() टी के माध्यम से readdir() से लौटे सूची गुजर रहा है टोपी केवल उन मानों को लौटाती है जो फाइलें हैं (निर्देशिकाओं, उपकरणों, नामित पाइप इत्यादि के विपरीत) और यह एक बिंदु से शुरू नहीं होता है (जो सूची का नाम @dots भ्रामक बनाता है, लेकिन यह उस प्रतिलिपि के कारण होता है जब उसने इसे कॉपी किया readdir() दस्तावेज से अधिक)। चूंकि यह उस निर्देशिका की सामग्री को सीमित करता है जो यह लौटाता है, मुझे नहीं लगता कि यह तकनीकी रूप से इस प्रश्न का सही उत्तर है, लेकिन यह Perl में फ़ाइल नामों को फ़िल्टर करने के लिए उपयोग किए जाने वाले एक सामान्य मुहावरे को दिखाता है, और मैंने सोचा कि यह दस्तावेज़ के लिए मूल्यवान होगा। एक अन्य उदाहरण है एक बहुत देखा है:

@list = grep !/^\.\.?$/, readdir(D); 

यह स्निपेट छोड़कर निर्देशिका संभाल डी से सभी सामग्री को पढ़ता है '।' और '..', क्योंकि वे सूची में उपयोग करने के लिए बहुत ही कम वांछित हैं।

6

यह एक लाइन (ध्यान दें '*' अंत में वाइल्डकार्ड)

@files = </path/to/directory/*>; 
# To demonstrate: 
print join(", ", @files); 
+0

क्या कोई मुझे समझा सकता है कि यह "गलत" क्यों है? क्योंकि यह साफ और सरल है (कुछ अन्य समाधानों के विपरीत), लेकिन यह स्पष्टीकरण के बिना डाउनमोड किया गया है। – rix0rrr

+0

मुझे मुश्किल से यह याद है कि ग्लोबबिंग इस्तेमाल किए गए खोल पर निर्भर है, शायद यही कारण है। – maaartinus

+0

यह सबसे अच्छा समाधान है, यह साफ है और यह मेरे लिए पूरी तरह से काम करता है। – mikemeli

1

यहाँ एक निर्देशिका संरचना और नकल फ़ाइलें froma बैकअप स्क्रिप्ट मैंने लिखा के माध्यम से recursing का एक उदाहरण है में कर देगा।

sub copy_directory { 
my ($source, $dest) = @_; 
my $start = time; 

# get the contents of the directory. 
opendir(D, $source); 
my @f = readdir(D); 
closedir(D); 

# recurse through the directory structure and copy files. 
foreach my $file (@f) { 
    # Setup the full path to the source and dest files. 
    my $filename = $source . "\\" . $file; 
    my $destfile = $dest . "\\" . $file; 

    # get the file info for the 2 files. 
    my $sourceInfo = stat($filename); 
    my $destInfo = stat($destfile); 

    # make sure the destinatin directory exists. 
    mkdir($dest, 0777); 

    if ($file eq '.' || $file eq '..') { 
    } elsif (-d $filename) { # if it's a directory then recurse into it. 
     #print "entering $filename\n"; 
     copy_directory($filename, $destfile); 
    } else { 
     # Only backup the file if it has been created/modified since the last backup 
     if((not -e $destfile) || ($sourceInfo->mtime > $destInfo->mtime)) { 
      #print $filename . " -> " . $destfile . "\n"; 
      copy($filename, $destfile) or print "Error copying $filename: $!\n"; 
     } 
    } 
} 

print "$source copied in " . (time - $start) . " seconds.\n";  
} 
8

IO::Dir अच्छा है और साथ ही एक बंधे हैंश इंटरफेस भी प्रदान करता है।

perldoc से:

use IO::Dir; 
$d = IO::Dir->new("."); 
if (defined $d) { 
    while (defined($_ = $d->read)) { something($_); } 
    $d->rewind; 
    while (defined($_ = $d->read)) { something_else($_); } 
    undef $d; 
} 

tie %dir, 'IO::Dir', "."; 
foreach (keys %dir) { 
    print $_, " " , $dir{$_}->size,"\n"; 
} 

तो आप की तरह कुछ कर सकते हैं:

tie %dir, 'IO::Dir', $directory_name; 
my @dirs = keys %dir; 
11

उपयोग करने के लिए एक त्वरित और गंदे समाधान है glob

@files = glob ('/path/to/dir/*'); 
+3

ध्यान देने योग्य है कि 'ग्लोब' विंडोज़ पर पथ में रिक्त स्थान के साथ अपेक्षित काम नहीं करता है- http://stackoverflow.com/questions/7898496/can-not-list- निर्देशिका- समावेश- स्पेस-using-perl-in -विंडोज़-प्लेटफ़ॉर्म – Kip

+0

कभी-कभी गंदे समाधान ठीक काम करते हैं। – serenesat

+0

यह छुपी हुई फ़ाइलें भी नहीं ढूंढ पाएगा (जो डॉट से शुरू होते हैं)। – josch

1

ऊपर की ही तरह, लेकिन मुझे लगता है कि "perldoc -f readdir" से सबसे अच्छा संस्करण (थोड़ा संशोधित) है:

opendir(DIR, $somedir) || die "can't opendir $somedir: $!"; 
@dots = grep { (!/^\./) && -f "$somedir/$_" } readdir(DIR); 
closedir DIR; 
4

आप DirHandle इस्तेमाल कर सकते हैं:

use DirHandle; 
$d = new DirHandle "."; 
if (defined $d) 
{ 
    while (defined($_ = $d->read)) { something($_); } 
    $d->rewind; 
    while (defined($_ = $d->read)) { something_else($_); } 
    undef $d; 
} 

DirHandleopendir(), closedir(), readdir(), और rewinddir() कार्यों के लिए एक विकल्प, क्लीनर इंटरफेस प्रदान करता है।

0

से: http://perlmeme.org/faqs/file_io/directory_listing.html

#!/usr/bin/perl 
use strict; 
use warnings; 

my $directory = '/tmp'; 

opendir (DIR, $directory) or die $!; 

while (my $file = readdir(DIR)) { 
    next if ($file =~ m/^\./); 
    print "$file\n"; 
} 

निम्न उदाहरण (perldoc -f readdir से एक कोड नमूने के आधार पर) सभी फाइलों (नहीं निर्देशिका) खुला निर्देशिका में से किसी अवधि से हो जाता है। फ़ाइल नाम सरणी @ डॉट्स में पाए जाते हैं।

#!/usr/bin/perl 

use strict; 
use warnings; 

my $dir = '/tmp'; 

opendir(DIR, $dir) or die $!; 

my @dots 
    = grep { 
     /^\./    # Begins with a period 
    && -f "$dir/$_" # and is a file 
} readdir(DIR); 

# Loop through the array printing out the filenames 
foreach my $file (@dots) { 
    print "$file\n"; 
} 

closedir(DIR); 
exit 0; 


closedir(DIR); 
exit 0; 
संबंधित मुद्दे