2009-01-12 13 views
8

जब मैं opendir, readdir, और closedir के साथ पर्ल में एक निर्देशिका पढ़ता हूं, फ़ंक्शन किसी भी विशिष्ट क्रम में फ़ाइलों को पढ़ने के लिए प्रतीत नहीं होता है (जो मैं बता सकता हूं)।सॉर्ट किए गए क्रम में निर्देशिका में फ़ाइलों को मैं कैसे पढ़ सकता हूं?

1224161460 
1228324260 
1229698140 

मैं संख्यात्मक क्रम में इन निर्देशिका है, जो सबसे पुराना निर्देशिका पहले डाल में पढ़ना चाहते हैं:

मैं एक निर्देशिका युग टाइमस्टैम्प द्वारा नामित उपनिर्देशिका है कि पढ़ रहा हूँ।

जब मैं readdir का उपयोग करता हूं, तो इसे पढ़ने वाला पहला 1228324260 है, जो मध्य है। मुझे पता है कि मैं निर्देशिका सामग्री को सरणी में डाल सकता हूं और सरणी को सॉर्ट कर सकता हूं, लेकिन क्या कोई विकल्प है जिसे मैं क्रमबद्ध क्रम में पढ़ने के लिए readdir पर जा सकता हूं? या शायद सबकुछ सरणी में डालने और सरणी को सॉर्ट करने से इसे पूरा करने का एक और शानदार तरीका है? ऐसा करने के लिए शायद वहां मॉड्यूल भी हैं, लेकिन हमारे पर्यावरण में मॉड्यूल स्थापित करना मुश्किल है, इसलिए जब तक कि यह एक अंतर्निहित मॉड्यूल न हो, मैं मॉड्यूल का उपयोग नहीं करना चाहूंगा ...

धन्यवाद!

संपादित के रूप में अनुरोध किया है, मैं कोड है कि मैं का उपयोग कर रहा पोस्टिंग कर रहा हूँ:,

opendir(my $data_dh, $data_dir) or die "Cannot open $data_dir\n"; 
while (my $name = readdir($data_dh)) { 
    next if ($name eq '.' or $name eq '..'); 
    my $full_path = "${data_dir}/${name}"; 
    next unless (-d $full_path); 
    process_dir($full_path); 
} 
closedir($data_dh); 
+0

मैं एक AIX बॉक्स पर पर्ल 5.8.2 का उपयोग कर रहा है, अगर यह एक फर्क – BrianH

+0

मैं जानता हूँ कि यह एक सरल स्क्रिप्ट है बनाता है, लेकिन आप अपने कोड पोस्ट कर सकते हैं तो हम की जरूरत नहीं है: आप एक foreach उपयोग कर सकते हैं इसे पुन: उत्पन्न करें? –

+1

process_dir से पहले और साइन आवश्यक नहीं है, और कुछ परिस्थितियों में हानिकारक हो सकता है। मैं आपको इसे हटाने के लिए सलाह दूंगा। –

उत्तर

13

readdir सरणी संदर्भ में कहा जा सकता है तो बस ऐसा करते हैं:

opendir(my $data_dh, $data_dir) or die "Cannot open $data_dir\n"; 
my @files = sort { $a <=> $b } readdir($data_dh); 
while (my $name = shift @files) { 
... 
+0

के बजाय" या "का उपयोग शुरू कर दूंगा, आपको {$ <=> $ b} ब्लॉक की आवश्यकता नहीं है; यहां डिफ़ॉल्ट डिफ़ॉल्ट हैं। – Svante

+2

नहीं, डिफ़ॉल्ट पर्याप्त नहीं है। डिफ़ॉल्ट प्रकार स्पष्ट रूप से नहीं, संख्यात्मक रूप से नहीं। 2001-09-09T01: 46: 40 से पहले टाइमस्टैम्प इसके बाद अधिकांश टाइमस्टैम्प की तुलना में क्रमबद्ध होंगे, क्योंकि यह 1,000,000,000 सेकंड बाधा तोड़ दिया था। –

+0

वास्तव में, ओपेन्डर यहां अधिक है। आपकी सबसे अच्छी शर्त ग्लोब() का उपयोग करना होगा ... कोई निर्देशिका चिंता करने के लिए संभालती है। –

5

आप इसे ग्लोब जादू के साथ आज़मा सकते हैं, ग्लोब एक क्रमबद्ध तरीके से काम करता प्रतीत होता है, इसलिए यह:

# Glob in scalar context iterates the result set internally 
while(defined(my $dir = glob($dir . '/*'))){ 
    print $dir, "\n"; 
    # $dir is fed ordered and with full names. 
} 

या

# Glob in list context returns all results. 
for(glob($dir.'/*')){ 
    print $dir , "\n"; 
    # also ordered. 
} 

काम करना चाहिए। बस, ग्लोब के साथ सावधान रहना यह है क्योंकि:

for(0..20){ 
    printf "%30s|%30s\n", glob($dir.'/*'), glob($dir.'/*'); 
} 

कुछ अर्द्ध जादुई करता है, और dir सामग्री प्रत्येक पंक्ति पर दो बार प्रिंट करता है। अर्थात्:

/foo/bar/a | /foo/bar/a 
/foo/bar/b | /foo/bar/b 
/foo/bar/c | /foo/bar/c 
/foo/bar/d | /foo/bar/d 
+1

यह शायद ऐसा करने का सबसे अच्छा तरीका है। opendir वास्तव में यहाँ overkill है। सरलीकरण के लिए –

5

बस किसी भी सूची ऑपरेटर है कि आप फिर से आदेश करना चाहते हैं के सामने एक sort फेंक देते हैं। आपको परिणामों को किसी सरणी में स्टोर करने की आवश्यकता नहीं है।

opendir my($dh), $dirname or die "Could not open directory [$dirname]: $!"; 

foreach my $file (sort { $a <=> $b } readdir $dh) 
    { 
    ... 
    } 
+0

++, लेकिन मुझे लगता है कि किसी ने आपका कोड मार्कअप (सॉर्ट ब्लॉक) तोड़ दिया। – converter42

+0

आह, हाँ, पूर्व ब्लॉक को कोण ब्रैकेट पसंद नहीं है, भले ही यह पूर्वावलोकन में अच्छी तरह से बाहर आता है। –

संबंधित मुद्दे

 संबंधित मुद्दे