Perl文件句柄 - 覆盖现有数据而不是追加/删除

时间:2017-09-24 16:52:07

标签: perl file-handling

cat -E test1.txt

输出:

car$
$
$

我想用“自行车”改变“汽车”并删除新的/空行。

这是按预期工作的:

#!/usr/bin/perl -w
open(FILE1,"<","./test1.txt"); @araj=<FILE1>; close(FILE1);
open(FILE2,">","./test1.txt");
map {
s@car@bike@; s@^\n@@;
} @araj;
print(FILE2 @araj);
close(FILE2);

cat -E test1.txt

输出100%对我来说是正确的:

bike$

但在上面的情况下我使用2x开/关文件。 所以我使用的是2x文件句柄 我只想使用 1x 文件句柄
(它用于学习目的,只是想了解+&gt; +&gt;&gt;&gt;&gt;如何工作...)。
例如:

#!/usr/bin/perl -w
open(FILE2,"+<","./test1.txt"); #what file handle should be here? +> , +>> >> .... ?
@araj=<FILE2>;
map {
s@car@bike@; s@^\n@@;
} @araj;
print(FILE2 @araj);
close(FILE2);

输出不正确:

car$
$
$
bike$

为什么会附加,但不会覆盖?当我使用其他文件句柄时,结果也不正确,例如空文件... 哪个文件句柄用于读取和覆盖?

2 个答案:

答案 0 :(得分:3)

  

为什么这是追加,但没有覆盖?

您首先读取所有数据,直到文件结束。这意味着下一次读取或写入的文件位置现在在您读取的所有数据之后,即在文件末尾。如果要从文件开头写入数据,则需要使用seek更改文件位置:

 seek($filehandle,0,0); # position at beginning of file

您编写的下一个数据将从该新文件位置开始写入,即从文件的开头开始。完成后,您可能需要使用truncate使用tell获取的当前文件位置,从文件中删除当前文件位置之后的所有数据:

 truncate($filehandle, tell($filehandle));

或者,整个计划:

use strict;
use warnings;
open(my $fh, "+<", "./test1.txt");
my @araj = <$fh>;
for(@araj) {
    s{car}{bike};
    s{^\n}{};
}
seek($fh, 0, 0);           # seek at the beginning of the file
print $fh @araj;
truncate($fh, tell($fh));  # remove everything after current file position
close($fh);

答案 1 :(得分:1)

在数组中读取文件后,文件句柄位置是文件的结尾。 然后,您应该通过seek函数(在文件的开头设置)perldoc seek更改文件句柄位置。 接下来,按truncate perldoc truncate

调整文件大小
#!/usr/bin/perl -w
open(FILE2,"+<","./test1.txt"); #what file handle should be here? +> , +>> >> .... ?
@araj=<FILE2>;
map {
s@car@bike@; s@^\n@@;
} @araj;

seek(FILE2, 0, 0);
print(FILE2 @araj);
truncate(FILE2, tell(FILE2));

close(FILE2);