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因此它永远不会有更多的文件参数。
  • ...这没关系,因为您在分配 to 之前打开文件句柄,而且@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 shell:

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 回答