2011-12-09 10 views
7

मैं एक निर्देशिका और सभी ईमेल (* .msg) फ़ाइलों के लिए शुरुआत करना चाहता हूं, शुरुआत में 'आरई' को हटा दें। मेरे पास निम्न कोड है लेकिन नाम विफल रहता है।निर्देशिका में फ़ाइलों का नाम बदलने के लिए पर्ल का उपयोग

opendir(DIR, 'emails') or die "Cannot open directory"; 
@files = readdir(DIR); 
closedir(DIR); 

for (@files){ 
    next if $_ !~ m/^RE .+msg$/; 
    $old = $_; 
    s/RE //; 
    rename($old, $_) or print "Error renaming: $old\n"; 
} 
+4

आप त्रुटि ($!) प्रिंट यदि आप क्या गलत है की एक विचार प्राप्त कर सकते हैं ... – pilcrow

+0

उनका कहना है कि बाहर के लिए धन्यवाद। त्रुटि 'ऐसी कोई फ़ाइल या निर्देशिका नहीं है'। मुझे आश्चर्य है क्योंकि $ पुराना फ़ाइल नाम सटीक है। – Johnathan1

+2

ध्यान दें कि 'नाम बदलें' क्रॉस-प्लेटफ़ॉर्म समर्थन का आनंद नहीं लेता है, जबकि 'फ़ाइल :: कॉपी'' 'move' फ़ंक्शन – Zaid

उत्तर

9

अपने ./emails निर्देशिका इन फ़ाइलें हैं, तो:

1.msg 
2.msg 
3.msg 

फिर अपने @files दिखेगा नाम बदलने से पहले ('.', '..', '1.msg', '2.msg', '3.msg') लेकिन अपने rename की तरह कुछ 'emails/1.msg' जैसे नाम, 'emails/2.msg', आदि चाहता है तो आप कर सकते हैं chdir:

chdir('emails'); 
for (@files) { 
    #... 
} 

आप शायद ch eck chdir वापसी मूल्य भी।

या जोड़ने निर्देशिका नाम अपने आप को:

rename('emails/' . $old, 'emails/' . $_) or print "Error renaming $old: $!\n"; 
# or rename("emails/$old", "emails/$_") if you like string interpolation 
# or you could use map if you like map 

आप grep का उपयोग कर अपने निर्देशिका पढ़ने और छानने गठबंधन करने के लिए चाहते हो सकता है:

my @files = grep { /^RE .+msg$/ } readdir(DIR); 

या यहाँ तक कि इस:

opendir(DIR, 'emails') or die "Cannot open directory"; 
for (grep { /^RE .+msg$/ } readdir(DIR)) { 
    (my $new = $_) =~ s/^RE //; 
    rename("emails/$_", "emails/$new") or print "Error renaming $_ to $new: $!\n"; 
} 
closedir(DIR); 
+0

उत्कृष्ट। इसे समझाने के लिए धन्यवाद। – Johnathan1

5

आप प्रतीत होता है कि glob-की तुलना में व्यवहार की तरह लगता है-व्यवहार के समान।

अंतर्निहित readdir सिस्टम कॉल केवल निर्देशिका के भीतर फ़ाइल नाम देता है, और इसमें दो प्रविष्टियां . और .. शामिल होंगी। यह पर्ल में readdir फ़ंक्शन के माध्यम से होता है, बस एमयू के उत्तर पर थोड़ी अधिक जानकारी देने के लिए।

वैकल्पिक रूप से, readdir का उपयोग करने के लिए बहुत कुछ नहीं है यदि आप किसी भी तरह से किसी भी सरणी में सभी परिणाम एकत्र कर रहे हैं।

@files = glob('emails/*'); 
+0

+1 मुझे याद दिलाने के लिए +1 कि 'ग्लोब' मौजूद है। 'ग्लोब' का नकारात्मक पक्ष यह है कि यह 'ईमेल /' उपसर्ग की उपस्थिति के कारण थोड़ा सा नाम उलझाने वाला है, यह एक मामूली मामूली समस्या है और हालांकि इससे निपटने के लिए तुच्छ है। –

2

जैसा कि पहले से ही बताया गया है, आपकी स्क्रिप्ट विफल होने के कारण विफल हो जाती है और स्क्रिप्ट का उपयोग समान नहीं होता है।

मैं एक और पारदर्शी उपयोग का सुझाव दूंगा। एक निर्देशिका हार्डकोडिंग एक अच्छा विचार नहीं है, आईएमओ। जैसा कि मैंने एक दिन सीखा जब मैंने कुछ मूल फाइलों को बदलने के लिए एक स्क्रिप्ट बनाई, हार्डकोडेड पथ के साथ, और मेरे विचार के एक सहयोगी ने अपनी प्रतियों को बदलने के लिए उधार लेने के लिए एक अच्छी लिपि होगी। ओह!

उपयोग:

perl script.pl "^RE " *.msg 

अर्थात regex, तो एक फ़ाइल ग्लोब सूची, जहां पथ स्क्रिप्ट के संबंध में सूचित किया जाता है, उदाहरण के लिए *.msg, emails/*.msg या यहां तक ​​कि /home/pat/emails/*.msg /home/foo/*.msg। (एकाधिक ग्लोब संभव)

पूर्ण पथ का उपयोग करने से उपयोगकर्ता को कोई संदेह नहीं होगा कि वह कौन सी फाइलें प्रभावित कर रही है, और यह स्क्रिप्ट को पुन: प्रयोज्य भी बनायेगी।

कोड:

use strict; 
use warnings; 
use v5.10; 
use File::Copy qw(move); 

my $rx = shift; # e.g. "^RE " 

if ($ENV{OS} =~ /^Windows/) { # Patch for Windows' lack of shell globbing 
    @ARGV = map glob, @ARGV; 
} 

for (@ARGV) { 
    if (/$rx/) { 
     my $new = s/$rx//r; # Using non-destructive substitution 
     say "Moving $_ to $new ..."; 
     move($_, $new) or die $!; 
    } 
} 
+0

+1: विंडोज़ के यूनिक्स-इफ़िकेशन से प्यार होना चाहिए :) – Zaid

+0

हाय, मुझे वास्तव में यह विचार पसंद है। मुझे लगता है कि मेरी $ new = s/$ rx // r लाइन पर एक त्रुटि हो रही है। आउटपुट 'बेवकूफ पाया गया है जहां ऑपरेटर "एस/$ आरएक्स // आर" के पास अपेक्षित था और उसी – Johnathan1

+0

@JP के पास वाक्यविन्यास त्रुटि। ओह, यह आपके पर्ल संस्करण के कारण हो सकता है .. आप किस संस्करण का उपयोग करते हैं? – TLP

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