2013-05-28 5 views
5

वहाँ किसी भी तरह से readdir द्वारा वापस सूची से एक आदेश की गारंटी करने के है?पर्ल readdir

मैं कोड है:

opendir(my $DIR, $src) or die "Error opening $src"; 

# Loop for each file in the directory 
while (my $file = readdir($DIR)) 
{ 
     print "$file\n"; 
} 

लेकिन यह यादृच्छिक क्रम में वापस आती है। अब मुझे पता है कि एक त्वरित Google खोज के माध्यम से बहुत सारे समाधान हैं, लेकिन मुझे सटीक ऑर्डर नहीं मिल रहा है .. मूल रूप से मैं फ़ोल्डरों को FIRST या LAST, और फ़ाइलों के बीच में नहीं दिखाना चाहता हूं।

उदाहरण के लिए, अभी अगर मैं फ़ोल्डर संरचना है:

folder 
folder 
file1 
file2 
file3 

मैं परिणाम प्राप्त:

file2 
folder 
folder 
file1 
file3 

जब वास्तव में मैं चाहता हूँ:

folder 
folder 
file1 
file2 
file3 

या:

file1 
file2 
file3 
folder 
folder 

इसे प्राप्त करने का कोई तरीका?

धन्यवाद।

+0

तरह किसी तरह का प्रयोग किया जाना चाहिए। –

उत्तर

4

आप पहली बार फ़ोल्डरों डाल और फिर फ़ाइल/dir नाम आधार पर क्रमित करके सॉर्ट कर सकते हैं,

# $src pointing to folder open with opendir 
my @sorted_dir = 
    map $_->[0], 
    sort { 
    $a->[1] <=> $b->[1] 
     || 
    $a->[0] cmp $b->[0] 
    } 
    map [ $_, -f "$src/$_" ], 
    readdir($DIR); 

समान प्रभाव के साथ प्राप्त किया जा सकता है,

for my $file (sort { -f "$src/$a" <=> -f "$src/$b" } readdir($DIR)) { 
    print "$file\n"; 
} 

यह अधिक बार धीमी है और यह रूप में अक्षम है निर्देशिका प्रविष्टि एक सादा फ़ाइल है अगर फाइल सिस्टम जांच में जाता है।

+0

धन्यवाद, मैं हालांकि एक और अधिक सुरुचिपूर्ण समाधान की उम्मीद कर रहा था। यदि सब कुछ विफल हो जाता है तो मैं वापस आऊंगा :) – Travv92

+0

सरल लेकिन धीमे विकल्प के साथ अपडेट किया गया। –

+0

धन्यवाद, यह एक अच्छा दिखने वाला है। यह सिम्बैब द्वारा प्रदान किए गए अन्य समाधान के साथ भी मुद्दा था, इसमें '$ src /' गायब था और यही कारण है कि यह काम नहीं कर रहा था! – Travv92

5

readdir द्वारा लौटाई गई सूची के प्रत्येक प्रविष्टि को देखकर आप sort का उपयोग कर सकते हैं।

opendir(my $DIR, '.') or die "Error opening "; 

foreach my $file (sort { -d $a <=> -d $b } readdir($DIR)) { 
    print "$file\n"; 
} 

यह फ़ोल्डरों को अंतिम देगा।

+0

हाय, जब मैं ऐसा करता हूं तो मुझे संख्यात्मक तुलना में अनियमित मूल्य का उपयोग मिलता है (<=>) '। – Travv92

+0

'<=>' के बजाय 'cmp' आज़माएं। – innaM

+0

अब मुझे स्ट्रिंग तुलना (सीएमपी) में अनियमित मूल्य का उपयोग मिलता है। दोनों उपज से '-d' को निकालने से कोई त्रुटि नहीं होती है (लेकिन स्पष्ट रूप से गलत आउटपुट) .. – Travv92

2

आप से List::MoreUtils

#!/usr/bin/env perl 

use strict; 
use warnings; 

use List::MoreUtils 'part'; 

my $dir = shift || '.'; 

opendir my $dh, $dir or die "Cannot open $dir"; 

my ($files, $dirs) = part { -d } sort readdir $dh; 

print "$_\n" for @$files, @$dirs; 

part उपयोग कर सकते हैं एक और विचार के लिए, आप File::Next पर लग सकता है।

+0

धन्यवाद, हालांकि मैं संकुल के बिना ऐसा करना पसंद करता हूं .. – Travv92

+0

यह काम करता है, इसे पढ़ने में आसान है, और आप लगभग निश्चित रूप से पहले से ही यह है। लेकिन ... आपकी पसंद है। –

3

foreach (sort readdir $dh) {} मेरे लिए ठीक काम करता है।

उदाहरण के लिए:

opendir (my $DIR, "$dir") || die "Error while opening $dir: $!\n"; 

foreach my $dirFileName(sort readdir $DIR) 
{ 
     next if $dirFileName eq '.' or $dirFileName eq '..'; 
     print("fileName: $dirFileName ... \n"); 
}