我正在尝试写入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";
答案 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: $!";
#!/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
。如果以二进制模式打开,则为两个字符。