1
    this
    is just
    an example.

上記がout.txtであると仮定しましょう。out.txtを読み、同じファイルに書き込みたい。

    <Hi >
    <this>
    <is just>
    <an example.>

out.txtを変更しました。いくつかの行の最初と最後にタグを追加したいと思います。ファイルを数回読み取るため、毎回別のファイルに書き込み続けることはできません。

EDIT 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";
     }
4

5 に答える 5

8

あなたがやろうとしていることのまさにその考えには欠陥があります。ファイルは次のように始まります

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
于 2012-09-28T05:10:57.347 に答える
5

メモリ内のコンテンツを読み取り、ファイルに書き込むときに必要な文字列を準備します。(SEEK_SETをゼロtバイトにする必要があります。

#!/usr/bin/perl

open(INFILE, "+<in.txt");
@a=<INFILE>;
seek INFILE, 0, SEEK_SET ;
foreach $i(@a)
{ 
    chomp $i;
    print INFILE "<".$i.">"."\n";
}

メモリに読み込まれるデータの量が心配な場合は、一時的な結果ファイルを作成し、最後に結果ファイルを元のファイルにコピーする必要があります。

于 2012-09-28T10:43:56.557 に答える
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(池上に感謝):大きなファイルを編集する必要があり、パフォーマンスが心配な場合は、このソリューションを使用しないでください。パフォーマンスの低下のほとんどは、小さなファイルで軽減されます(2MB未満ですが、これはmemoryargを使用して構成できます)。

于 2012-09-28T05:12:30.113 に答える
1

1つのオプションは、ファイルを2回開くことです。1回だけ読み取り専用で開き、データを読み取り、閉じて処理し、再度読み取り/書き込み(追加なし)してデータを書き込み、閉じます。他の誰かがファイルを必要とする場合に備えて、ファイルを開く時間を最小限に抑えることができるため、これは良い習慣です。

一度だけ開きたい場合は、+<ファイルタイプを使用できseekます。読み取りと書き込みの間の呼び出しを使用して、ファイルの先頭に戻ります。それ以外の場合は、読み取りを終了し、ファイルの最後に移動して、そこに書き込みを開始します。これが、表示されている動作を取得する理由です。

于 2012-09-28T05:02:31.347 に答える
0

指定する必要があります

use Fcntl qw(SEEK_SET);

使用するために

seek INFILE, 0, SEEK_SET;

例を示してくれたuser1703205に感謝します。

于 2014-04-24T13:25:01.773 に答える