perl:在第N位写入文件

时间:2010-09-08 11:24:03

标签: perl

我正在尝试写入Nth POSITION的档案。我试过下面的例子,但最后写了。请帮助实现这一目标。

#!/usr/bin/perl

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

$POS=5;

   seek(FILE,$POS,0);

   print FILE "CP1";

5 个答案:

答案 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': $!";

答案 1 :(得分:3)

您正在以读写附加模式打开文件。尝试以读写模式打开文件:

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

另外,请注意使用三个参数open,词法文件句柄和$!

#!/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

答案 2 :(得分:2)

这对我有用

use strict;
use warnings;

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

seek( $fh, 3, 0 );

print $fh "WH00t?";

这也是open()更“现代”的用法,请参阅http://perldoc.perl.org/functions/open.html

当$ fh超出范围时,文件将被关闭..

答案 3 :(得分: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;

答案 4 :(得分:-1)

如果您的文件是行或面向记录的,您可以使用核心模块Tie::File轻松插入行或修改单独的行。这将允许将文件视为数组并使用Perl字符串和数组操作修改内存中的文件。使用这种方法,您可以安全地操作大于RAM的大文件。

以下是一个例子:

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来根据您的请求进行修改和插入。您可以在数组模型之间放置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。如果以二进制模式打开,则为两个字符。