2010-12-19 11 views
8

में पढ़ने और लिखने (संलग्न नहीं) के लिए फ़ाइल खोलें मानक पर्ल पुस्तकालयों के साथ फ़ाइल खोलने और इसे संपादित करने के लिए कोई तरीका है, इसे बंद किए बिना इसे फिर से खोलें? मुझे पता है कि कैसे करना है फ़ाइल को बंद करने वाली स्ट्रिंग में फ़ाइल को पढ़ने के लिए फ़ाइल को फिर से लिखना; या पढ़ें और फिर फ़ाइल के अंत में संलग्न करें।पर्ल

निम्नलिखित में वर्तमान में काम करता है; मैं इसे खोल सकते हैं और इसे दो बार बंद करने के लिए, एक बार के बजाय है:

#!/usr/bin/perl 
use warnings; use strict; 
use utf8; binmode(STDIN, ":utf8"); binmode(STDOUT, ":utf8"); 
use IO::File; use Cwd; my $owd = getcwd()."/"; # OriginalWorkingDirectory 
use Text::Tabs qw(expand unexpand); 
$Text::Tabs::tabstop = 4; #sets the number of spaces in a tab 

opendir (DIR, $owd) || die "$!"; 
my @files = grep {/(.*)\.(c|cpp|h|java)/} readdir DIR; 
foreach my $x (@files){ 
    my $str; 
    my $fh = new IO::File("+<".$owd.$x); 
    if (defined $fh){ 
     while (<$fh>){ $str .= $_; } 
     $str =~ s/(|\t)+\n/\n/mgos;#removes trailing spaces or tabs 
     $str = expand($str);#convert tabs to spaces 
     $str =~ s/\/\/(.*?)\n/\/\*$1\*\/\n/mgos;#make all comments multi-line. 
     #print $fh $str;#this just appends to the file 
     close $fh; 
    } 
    $fh = new IO::File(" >".$owd.$x); 
    if (defined $fh){ 
     print $fh $str; #this just appends to the file 
     undef $str; undef $fh; # automatically closes the file 
    } 
} 
+0

1k + विचार और केवल 1 अपवॉट। । । – GlassGhost

+0

2 अपवॉट्स अब: $ 0 I32 :-) – GLES

उत्तर

15

आप पहले से ही मोड <+ साथ खोलकर पढ़ने और लिखने के लिए फ़ाइल को खोला, तो आप सिर्फ इसके साथ उपयोगी कुछ भी नहीं कर रहे हैं - यदि आप वर्तमान स्थिति (फ़ाइल के अंत) को लिखने के बजाय फ़ाइल की सामग्री को प्रतिस्थापित करना चाहते हैं तो आपको शुरुआत में seek चाहिए, लिखने के लिए आपको क्या चाहिए, और फिर truncate यह सुनिश्चित करने के लिए कि कुछ भी नहीं बचा है अगर आपने फ़ाइल को छोटा बनाया है।

लेकिन चूंकि आप जो करने का प्रयास कर रहे हैं वह फ़ाइल की जगह फ़िल्टरिंग है, तो क्या मैं सुझाव दे सकता हूं कि आप अपने सभी काम करने के बजाए पेर्ल के इनस्थल संपादन एक्सटेंशन का उपयोग करें?

#!perl 
use strict; 
use warnings; 
use Text::Tabs qw(expand unexpand); 
$Text::Tabs::tabstop = 4; 

my @files = glob("*.c *.h *.cpp *.java"); 

{ 
    local $^I = ""; # Enable in-place editing. 
    local @ARGV = @files; # Set files to operate on. 
    while (<>) { 
     s/(|\t)+$//g; # Remove trailing tabs and spaces 
     $_ = expand($_); # Expand tabs 
     s{//(.*)$}{/*$1*/}g; # Turn //comments into /*comments*/ 
     print; 
    } 
} 

और यह वह कोड है जो आपको चाहिए - पेर्ल बाकी को संभालती है। $^I variable को सेट करना -i commandline flag का उपयोग करने के बराबर है। मैंने आपके कोड में कई बदलाव किए हैं - use utf8 स्रोत में कोई शाब्दिक यूटीएफ -8 नहीं है, binmode आईएनजी स्टडीन और स्टडआउट प्रोग्राम के लिए कुछ भी नहीं करता है जो कभी भी स्टडीन या स्टडआउट का उपयोग नहीं करता है, सीडब्ल्यूडी को बचाने से कुछ भी नहीं करता एक कार्यक्रम के लिए जो chdir एस कभी नहीं। प्रत्येक फ़ाइल को एक बार में पढ़ने का कोई कारण नहीं था इसलिए मैंने इसे लाइनवॉइड में बदल दिया, और रेगेक्स को कम अजीब बना दिया (और आकस्मिक रूप से, /o रेगेक्स संशोधक इन दिनों लगभग ठीक कुछ भी नहीं है, हार्ड-टू-बग बग जोड़ने के अलावा आपके कोड में)।

+1

+1: प्रक्रिया लाइन-आधारित है। क्या होगा यदि मैं regexp का उपयोग करना चाहता हूं जिसमें नई लाइन है? – friedo

+0

@ हॉब्स के लिए डी – solotim

+1

@ सोलोटीम विवरण पर निर्भर करता है। आप '$/'' से अधिक उचित में' $/'को बदल सकते हैं, विशेष रूप से, यदि आप '$ /'' को 'undef'' पर सेट करते हैं तो पर्ल पूरी फ़ाइल सामग्री को एक पठन में पढ़ेगा, आपको उन्हें संशोधित करें, और फिर वापस लिखें। मेमोरी काफी बड़ी है कि यह कई फाइलों के लिए एक उचित दृष्टिकोण है। लेकिन अगर ऐसा नहीं है, तो आपको अपने काम पर काम करने की आवश्यकता होगी। – hobbs