2010-09-08 12 views
5

पर फ़ाइल लिखना मैं एनएच पॉजिशन में फ़ाइल में लिखने की कोशिश कर रहा हूं। मैंने नीचे उदाहरण के साथ प्रयास किया है लेकिन यह अंत में लिखता है। कृपया इसे प्राप्त करने में मदद करें।perl: एनएच स्थिति

#!/usr/bin/perl 

open(FILE,"+>>try.txt") 
or 
die ("Cant open file try.txt"); 

$POS=5; 

    seek(FILE,$POS,0); 

    print FILE "CP1"; 
+1

क्या आपने एक ऐसे मोड का उपयोग करने का प्रयास किया है जो संलग्न नहीं करता है? जैसे कि: ओपन (मेरा $ एफएच, '<+', "try.txt") या $ die !; (यह ओपन() का एक और "आधुनिक" उपयोग भी है, http://perldoc.perl.org/functions/open.html देखें) –

+0

@ ओविंद स्काकर यह '" <"' '' '" <+ " '। –

+0

@chas सही आप कर रहे हैं .. –

उत्तर

3

आप फ़ाइल को रीड-राइटिंग एपेंडिंग मोड में खोल रहे हैं। इसके अलावा

my $file = "try.txt"; 
open my $fh, "+<", $file 
    or die "could not open $file: $!"; 

, तीन तर्क open, शाब्दिक filehandle, और $! के उपयोग पर ध्यान दें: पढ़ने-लिखने मोड में फ़ाइल खोलने का प्रयास करें।

#!/usr/bin/perl 

use strict; 
use warnings; 

#create an in-memory file 
my $fakefile = "1234567890\n"; 
open my $fh, "+<", \$fakefile 
    or die "Cant open file: $!"; 

my $offset = 5; 

seek $fh, $offset, 0 
    or die "could not seek: $!"; 

print $fh "CP1"; 

print $fakefile; 

प्रिंट उपरोक्त कोड:

12345CP190 
+0

हाय चास यह वां स्थिति यानी पर चरित्र संलग्न करने के लिए एन 1 को वां चरित्र को स्थानांतरित एन 1 एन 2 और इतने पर – vrbilgi

+0

@ user430294 संभव हो सकता है: नहीं सच में। आपको वास्तव में एन के बाद सामग्री को पढ़ना होगा और फिर उसे दूसरी स्थिति में लिखना होगा। –

+0

@ user430294 नहीं, फाइलें इस तरह से काम नहीं करती हैं। –

2

यह मेरे

use strict; 
use warnings; 

open(my $fh, '+<', 'foo.txt') or die $!; 

seek($fh, 3, 0); 

print $fh "WH00t?"; 

लिए काम करता है यह भी खुला() का एक और अधिक "आधुनिक" इस्तेमाल होता है, को देखने के http://perldoc.perl.org/functions/open.html

फ़ाइल बंद हो जाएगी जब $ एफएच दायरे से बाहर हो जाता है ..

+0

@ स्काकर आपका समाधान ठीक काम कर रहा है। लेकिन यह फ़ाइल में मौजूद चरित्र को बदल रहा है। मैं एनएच स्थिति पर सामग्री को जोड़ना चाहता हूं यानी एनएच चरित्र को एन + 1 एन + 1 से एन + 2 तक ले जाना चाहता हूं। – vrbilgi

+0

एचएम .. आप इसे पढ़ सकते हैं और फिर इसे फिर से लिख सकते हैं .. शायद किसी के पास बेहतर समाधान हो .. लेकिन मुझे लगता है कि "संलग्न मोड" (>>) का मतलब है कि यह फ़ाइल के अंत में लिखना शुरू कर देता है, ताकि वह वह नहीं है जो आप चाहते हैं। –

4

अगर मैं तुम्हें सही ढंग से समझ, अगर फ़ाइल सामग्री

123456789

हैं आप

1234CP157689

है कि बदलने के लिए आप प्राप्त नहीं कर सकता चाहते हैं कि (चाहे प्रोग्रामिंग भाषा के) open को आपूर्ति साधनों का उपयोग।

आपको स्रोत फ़ाइल और अन्य अस्थायी फ़ाइल खोलने की आवश्यकता है (File::Temp देखें। स्रोत से सम्मिलन बिंदु तक पढ़ें और सामग्री को अस्थायी फ़ाइल में लिखें, लिखें कि आप क्या सम्मिलित करना चाहते हैं, फिर शेष का लिखें अस्थायी फ़ाइल के लिए स्रोत फ़ाइल, स्रोतों को बंद करने और rename अस्थायी।

आप इस seek उपयोग करते हुए, दोनों फ़ाइलों द्विआधारी मोड में खोला जाना चाहिए क्या करने जा रहे हैं।

यहाँ का उपयोग कर एक उदाहरण है लाइन उन्मुख इनपुट और टेक्स्ट मोड:

#!/usr/bin/perl 

use strict; use warnings; 
use File::Temp qw(:POSIX); 

my $source = 'test.test'; 
my $temp = tmpnam; 

open my $source_h, '<', $source 
    or die "Failed to open '$source': $!"; 

open my $temp_h, '>', $temp 
    or die "Failed to open '$temp' for writing: $!"; 

while (my $line = <$source_h>) { 
    if ($line =~ /^[0-9]+$/) { 
     $line = substr($line, 0, 5) . "CP1" . substr($line, 5); 
    } 
    print $temp_h $line; 
} 

close $temp_h 
    or die "Failed to close '$temp': $!"; 

close $source_h 
    or die "Failed to close '$source': $!"; 

rename $temp => $source 
    or die "Failed to rename '$temp' to '$source': $!"; 
2

फ़ंक्शन में एक स्ट्रिंग "सम्मिलित करना" (अधिकतर) जगह पर किया जा सकता है। हल्के ढंग से इस्तेमाल किए गए truncate अंतर्निहित फ़ंक्शन देखें।

open my $fh, '+<', $file or die $!; 
seek $fh, 5, 0; 
$/ = undef; 
$x = <$fh>; # read everything after the 5th byte into $x 
truncate $fh, 5; 
print $fh "CPI"; 
print $fh $x; 
close $fh; 
+0

+1 मुझे यह पसंद है! क्या विंडोज़ प्लेटफ़ॉर्म के लिए फ़ाइल को बिन मोड में होना चाहिए? – dawg

-1

यदि आपकी फ़ाइल लाइन या रिकॉर्ड उन्मुख, आप लाइनों डालने या कोर मॉड्यूल Tie::File के साथ आसानी से अलग-अलग लाइनों संशोधित कर सकते हैं इस फ़ाइल में एक सरणी और पर्ल स्ट्रिंग और सरणी हेरफेर के रूप में इलाज किया जा करने की अनुमति देगा का उपयोग किया जा रहा है स्मृति में फ़ाइल को संशोधित करने के लिए। आप इस विधि के साथ अपनी रैम से बड़ी फ़ाइलों पर सुरक्षित रूप से काम कर सकते हैं।

यहाँ एक उदाहरण है:

use strict; use warnings; 
use Tie::File; 

#create the default .txt file: 
open (my $out, '>', "nums.txt") or die $!; 
while(<DATA>) { print $out "$_"; } 
close $out or die $!; 

tie my @data, 'Tie::File', "nums.txt" or die $!; 

my $offset=5; 
my $insert="INSERTED"; 

#insert in a string: 
$data[0]=substr($data[0],0,$offset).$insert.substr($data[0],$offset) 
    if (length($data[0])>$offset); 

#insert a new array element that becomes a new file line:  
splice @data,$offset,0,join(':',split(//,$insert)); 

#insert vertically: 
$data[$_]=substr($data[$_],0,$offset) . 
      substr(lc $insert,$_,1) . 
      substr($data[$_],$offset) for (0..length($insert)); 

untie @data; #close the file too... 

__DATA__ 
123456789 
234567891 
345678912 
456789123 
567891234 
678912345 
789123456 
891234567 
912345678 

आउटपुट:

12345iINSERTED6789 
23456n7891 
34567s8912 
45678e9123 
56789r1234 
I:N:St:E:R:T:E:D 
67891e2345 
78912d3456 
891234567 
912345678 

Tie::File साथ फ़ाइल संशोधनों जगह में बने होते हैं और के रूप में सरणी संशोधित किया गया है। आप अनुरोध के अनुसार संशोधित और सम्मिलित करने के लिए फ़ाइल की पहली पंक्ति पर Tie::File का उपयोग कर सकते हैं। आप वैकल्पिक रूप से सरणी mods के बीच sleep डाल सकते हैं और फ़ाइल पर tail -n +0 -f का उपयोग करें और फ़ाइल परिवर्तन देखने के यदि आप चाहें तो ...

, यदि आपकी फ़ाइल उचित आकार है और आप वर्ण की तरह ही यह इलाज करना चाहते हैं, आप पढ़ सकते हैं पूरी फ़ाइल मेमोरी में, डेटा पर स्ट्रिंग ऑपरेशन करें, फिर संशोधित डेटा को वापस लिखें। पर विचार करें:

use strict; use warnings; 

#creat the default .txt file: 
open (my $out, '>', "nums.txt") or die $!; 
while(<DATA>) { print $out "$_"; } 
close $out or die $!; 

my $data; 
open (my $in, '<', "nums.txt") or die $!; 
{ local $/=undef; $data=<$in>; } 
close $in or die $!; 

my $offset=5; 
my $insert="INSERTED"; 

open (my $out, '>', "nums.txt") or die $!; 
print $out substr($data,0,$offset).$insert.substr($data,$offset); 
close $out or die $!; 

__DATA__ 
123456789 
2 
3 
4 
5 
6 
7 
8 
9 

आउटपुट:

12345INSERTED6789 
2 
3 
4 
5 
6 
7 
8 
9 

आप पात्रों के रूप में फ़ाइलों का इलाज करते हैं, तो सावधान रहना है कि Windows के तहत, पाठ मोड में फ़ाइलों को एक नई लाइन के लिए एक \r\n है। द्विआधारी मोड में खोले जाने पर यह दो अक्षर हैं।

+0

यादृच्छिक नीचे वोट क्यों? – dawg