2013-02-08 96 views
1

我是這個網站的新手,需要幫助從多個文本文件中刪除重複的條目(在一個循環中)。嘗試下面的代碼,但這並不是刪除多個文件的重複,但它是爲單個文件工作。從perl中的多個文本文件中刪除重複項?

代碼:

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 ; 
    } 
} 

感謝, 藝術

+0

嘗試'未來如果$ {看到$ _}> 0;' –

+2

您還沒有打開多個文件,你只有一個輸入文件名存在,所以你怎麼能指望它會影響多個文件? – TLP

+0

你正在尋找所有文件中的重複內容,還是僅僅在每個單獨的文件中重複? – TLP

回答

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 
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循環之外,您將檢查所有文件中的重複項。我不確定你喜歡哪一個。

+0

請修改:更改!$看過{$ _]至!$看過{$ _}。我試圖自己改變它,但它至少需要改變6個字符:) – Tony

相關問題