1

私はこのサイトに不慣れで、複数のテキスト ファイルから重複したエントリを削除するのに助けが必要です (ループ内)。以下のコードを試しましたが、これは複数のファイルの重複を削除していませんが、単一のファイルでは機能しています。

コード :

my $file = "$Log_dir/File_listing.txt";
my $outfile  = "$Log_dir/Remove_duplicate.txt";; 

open (IN, "<$file") or die "Couldn't open input file: $!"; 
open (OUT, ">$outfile") or die "Couldn't open output file: $!"; 
my %seen = ();
{
  my @ARGV = ($file);
  # local $^I = '.bac';
  while(<IN>){
    print OUT $seen{$_}++;
    next if $seen{$_} > 1;
    print OUT ;
  }
}

ありがとう、アーツ

4

2 に答える 2

3

スクリプトのエラー:

  • (の新しいコピー)@ARGV$fileで上書きするため、これ以上ファイル引数を持つことはできません。
  • ...に代入する前にファイルハンドルを開くため、これは問題ではありません。@ARGVさらに、引数をループし{ ... }ないため、目的を果たさないコードの周りにブロックがあるだけです。
  • %seenリセットしない限り、開いたすべてのファイルの重複排除データが含まれます。
  • カウント$seen{$_}を出力ファイルに出力しますが、これは必要ないと確信しています。

ひし形演算子を使用して引数の暗黙的なオープンを使用することもできます@ARGVが、(おそらく) 新しいファイルごとに適切な出力ファイル名を割り当てる必要があるため、そのようなソリューションでは望ましくない複雑さが生じます。

use strict;
use warnings;                      # always use these

for my $file (@ARGV) {             # loop over all file names
    my $out = "$file.deduped";     # create output file name
    open my $infh,  "<", $file or die "$file: $!";
    open my $outfh, ">", $out  or die "$out: $!";
    my %seen;
    while (<$infh>) {
        print $outfh $_ if !$seen{$_}++;   # print if a line is never seen before
    }
}

レキシカルスコープ%seenの変数を使用すると、スクリプトは個々のファイル内の重複をチェックすることに注意してください。変数を for ループの外に移動すると、すべてのファイルで重複がないかチェックされます。あなたがどちらを好むかわかりません。

于 2013-02-08T09:11:57.547 に答える
1

あなたには複数の行が含まれていると思いますFile_listing.txtか?その場合は、bash シェルを使用してください。

sort --unique <File_listing.txt >Remove_duplicate.txt

または、Perl の方が好きな場合:

perl -lne '$seen{$_}++ and next or print;' <File_listing.txt >Remove_duplicate.txt
于 2013-02-08T09:08:13.497 に答える