this
is just
an example.
让我们假设上面是 out.txt 。我想阅读 out.txt 并写入同一个文件。
<Hi >
<this>
<is just>
<an example.>
修改 out.txt 。 我想在某些行的开头和结尾添加标签。 由于我将多次阅读该文件,因此每次都无法将其写入不同的文件。
编辑1
我尝试使用"+<"
,但它给出了这样的输出:
Hi
this
is just
an example.
<Hi >
<this>
<is just>
<an example.>
**out.txt**
编辑2 代码参考:
open(my $fh, "+<", "out.txt");# or die "cannot open < C:\Users\daanishs\workspace\CCoverage\out.txt: $!";
while(<$fh>)
{
$s1 = "<";
$s2 = $_;
$s3 = ">";
$str = $s1 . $s2 . $s3;
print $fh "$str";
}
答案 0 :(得分:7)
你想要做的事情的想法是有缺陷的。该文件以
开头H i / t h i s / ...
如果您要更改它,在处理完第一行后会看起来如下:
< H i > / i s / ...
请注意你是如何破坏“th”的?您需要制作文件的副本,修改副本,用副本替换原件。
最简单的方法是在内存中制作此副本。
my $file;
{ # Read the file
open(my $fh, '<', $qfn)
or die "Can't open \"$qfn\": $!\n";
local $/;
$file = <$fh>;
}
# Change the file
$file =~ s/^(.*)\n/<$1>\n/mg;
{ # Save the changes
open(my $fh, '>', $qfn)
or die "Can't create \"$qfn\": $!\n";
print($fh $file);
}
如果您想改用磁盘:
rename($qfn, "$qfn.old")
or die "Can't rename \"$qfn\": $!\n";
open(my $fh_in, '<', "$qfn.old")
or die "Can't open \"$qfn\": $!\n";
open(my $fh_out, '>', $qfn)
or die "Can't create \"$qfn\": $!\n";
while (<$fh_in>) {
chomp;
$_ = "<$_>";
print($fh_out "$_\n");
}
unlink("$qfn.old");
使用技巧,上面的内容可以简化为
local @ARGV = $qfn;
local $^I = '';
while (<>) {
chomp;
$_ = "<$_>";
print(ARGV "$_\n");
}
或者作为一个单行:
perl -i -pe'$_ = "<$_>"' file
答案 1 :(得分:4)
读取内存中的内容,然后在写入文件时准备必需的字符串。 (需要SEEK_SET到零字节。
#!/usr/bin/perl
open(INFILE, "+<in.txt");
@a=<INFILE>;
seek INFILE, 0, SEEK_SET ;
foreach $i(@a)
{
chomp $i;
print INFILE "<".$i.">"."\n";
}
如果您担心在内存中读取的数据量,则必须创建临时结果文件,最后将结果文件复制到原始文件。
答案 2 :(得分:2)
您可以使用Tie::File
轻松随意访问文件中的行:
use Tie::File;
use strict;
use warnings;
my $filename = "out.txt";
my @array;
tie @array, 'Tie::File', $filename or die "can't tie file \"$filename\": $!";
for my $line (@array) {
$line = "<$line>";
# or $line =~ s/^(.*)$/<$1>/g; # -- whatever modifications you need to do
}
untie @array;
免责声明:当然,此选项仅在文件未与其他进程共享时才可行。否则,您可以在修改文件时使用flock
来阻止共享访问。
免责声明-2(感谢ikegami):如果您需要编辑大文件并关注性能,请不要使用此解决方案。对于小文件(小于2MB,尽管可以使用memory
arg进行配置),大多数性能损失都得到了缓解。
答案 3 :(得分:1)
一个选项是打开文件两次:以只读方式打开它,读取数据,关闭数据,处理数据,再次打开读写(无追加),写入数据,然后关闭它。这是一种很好的做法,因为它可以最大限度地缩短文件打开的时间,以防其他人需要它。
如果您只想打开一次,那么您可以使用+<
文件类型 - 只需在读取和写入之间使用seek
调用即可返回文件的开头。否则,你完成阅读,在文件的末尾,并开始写在那里,这就是你得到你所看到的行为的原因。
答案 4 :(得分:0)
需要指定
use Fcntl qw(SEEK_SET);
为了使用
seek INFILE, 0, SEEK_SET;
感谢user1703205的例子。