2017-09-24 3 views
2
cat -E test1.txt 

出力削除/追加上書き:Perlのファイルハンドル - データを既存の代わりに

car$ 
$ 
$ 

を私は「自転車」と「車」に変更し、新しい/空行を削除します。

これは期待通りに動作している:/

​​

しかし、上記の場合には、私は、2倍の開口部を使用しています:

#!/usr/bin/perl -w 
open(FILE1,"<","./test1.txt"); @araj=<FILE1>; close(FILE1); 
open(FILE2,">","./test1.txt"); 
map { 
[email protected]@[email protected]; [email protected]^\[email protected]@; 
} @araj; 
print(FILE2 @araj); 
close(FILE2); 

cat -E test1.txt 

出力は私のために、100%正確ですファイルを閉じます。 私は2xファイルハンドルを使用しています。
1xファイルハンドル
(これは学習目的で、単に+> + >>どのように動作しているか理解しようとしています...)のみ使用します。たとえば

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

出力が正しくありません。

car$ 
$ 
$ 
bike$ 

なぜこれが追加、ない上書きされますか?他のファイルハンドルを使用すると、結果も間違っています。例えば、空のファイル... 読み書きのために使用されるファイルハンドルはどれですか?

+0

https://perldoc.perl.org/functions/seek.html –

+0

@ikegami感謝して、ファイルサイズを変更します。修正されました。 – collector1871

答えて

2

これはなぜ追加されますが、上書きされませんか?

ファイルの最後まですべてのデータを最初に読み取っています。これは、次の読み取りまたは書き込みのファイル位置が、読み取ったすべてのデータの後、つまりファイルの最後にあることを意味します。あなたはファイルの先頭からのデータを書き込みたい場合は、seekを使用してファイルの位置を変更する必要があります。

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

あなたが書いた次のデータは、その後、すなわち初めから、この新しいファイル位置で始まる書き込まれますファイルの設定が完了したら、あなたはtellを持っている現在のファイル位置でtruncateを使用してファイルから現在のファイル位置の後に任意のデータを削除する必要があります:

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); 
+0

ありがとう、私のための素晴らしい答え – collector1871

1

ファイルを読み込んだ後、ファイルハンドルの位置はファイルの最後です。 次にファイルハンドルの位置をseek関数(ファイルの先頭に設定)perldoc seekで変更する必要があります。 次はあなたがtruncateperldoc truncate

#!/usr/bin/perl -w 
open(FILE2,"+<","./test1.txt"); #what file handle should be here? +> , +>> >> .... ? 
@araj=<FILE2>; 
map { 
[email protected]@[email protected]; [email protected]^\[email protected]@; 
} @araj; 

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

close(FILE2); 
+0

ありがとう、それは働いている(これも良い答えです) – collector1871

関連する問題