2013-04-02 6 views
0

У меня есть 4 файла, каждый файл, который я читал в его собственный массив. Оттуда я сравниваю файлы A, B и C друг с другом. На каждом шаге я распечатываю список отсутствующих цифр.Лучший способ сравнить 4 массива

Сравнить А Б затем B в список печати файлов, найденных в A и не B, и наоборот

Сравнить А до С, то С к списку печати файлов, найденных в A, но не C и наоборот

Сравнить B к C и C к B печать списка файлов, найденных в B, но не C и наоборот

Тогда я должен принимать значения из этих сравнений и сравнить их в файл D только печать файлы, которые не найдены в файле D

Вот код, который я имею до сих пор. Я просто думаю, что может быть лучший способ сделать это, и я хотел бы немного помочь с этим.

[КОД]

sub compare { 

    my ($nf, $of, $inf, $infw) = @_; 

    open NF, $nf or die $!; 
    my @note_file = <NF>; 
    close NF; 

    open OF, $of or die $!; 
    my @order_file = <OF>; 
    close OF; 

    open INF, $inf or die $!; 
    my @invoice_file = <INF>; 
    close INF; 

    open INFW, $infw or die $!; 
    my @invoicefw_file = <INFW>; 
    close INFW; 

    my $lc1 = List::Compare->new(\@note_file,\@order_file); 
    my @unique_in_note_file = $lc1->get_unique; 
    my @unique_in_order_file = $lc1->get_complement; 
    print "The following files exist only in the Brighton-Note file and not in the Brighton-Order file : " . "\n\n" . join("\n", @unique_in_note_file) . "\n" if(scalar(@unique_in_note_file) > 0); 
    print "The following files exist only in the Brighton-Order file and not in the Brighton-Note file : " . "\n\n" . join("\n", @unique_in_order_file) . "\n" if(scalar(@unique_in_order_file) > 0); 

    my $lc2 = List::Compare->new(\@note_file,\@invoice_file); 
    @unique_in_note_file = $lc2->get_unique; 
    my @unique_in_invoice_file = $lc2->get_complement; 
    print "The following files exist only in the Brighton-Note file and not in the Web-Sales file : " . "\n\n" . join("\n", @unique_in_note_file) . "\n" if(scalar(@unique_in_note_file) > 0); 
    print "The following files exist only in the Web-Sales file and not in th Brighton-Note file : " . "\n\n" . join("\n", @unique_in_invoice_file) . "\n" if(scalar(@unique_in_invoice_file) > 0); 

    my $lc3 = List::Compare->new(\@order_file, \@invoice_file); 
    @unique_in_order_file = $lc3->get_unique; 
    @unique_in_invoice_file = $lc3->get_complement; 
    print "The following files exist only in the Brighton-Order file and not in the Web-Sales file : " . "\n\n" . join("\n", @unique_in_order_file) . "\n" if(scalar(@unique_in_order_file) > 0); 
    print "The following files exist only in the Web-Sales file and not in th Brighton-Order file : " . "\n\n" . join("\n", @unique_in_invoice_file) . "\n" if(scalar(@unique_in_invoice_file) > 0); 

    my $lc4 = List::Compare->new(\@unique_in_note_file,\@invoicefw_file); 
    my @unique_in_notefw_file = $lc4->get_unique; 
    my @unique_in_invoicefw_file = $lc4->get_complement; 
    print "The following files exist only in the Brighton-Note file and not in the Web-SalesFW file : " . "\n\n" . join("\n", @unique_in_notefw_file) . "\n" if(scalar(@unique_in_notefw_file) > 0); 
    print "The following files exist only in the Web-SalesFW file and not in th Brighton-Note file : " . "\n\n" . join("\n", @unique_in_invoicefw_file) . "\n" if(scalar(@unique_in_invoicefw_file) > 0); 

    my $lc5 = List::Compare->new(\@unique_in_order_file,\@invoicefw_file); 
    my @unique_in_orderfw_file = $lc5->get_unique; 
    @unique_in_invoicefw_file = $lc5->get_complement; 
    print "The following files exist only in the Brighton-Order file and not in the Web-SalesFW file : " . "\n\n" . join("\n", @unique_in_orderfw_file) . "\n" if(scalar(@unique_in_orderfw_file) > 0); 
    print "The following files exist only in the Web-SalesFW file and not in th Brighton-Order file : " . "\n\n" . join("\n", @unique_in_invoicefw_file) . "\n" if(scalar(@unique_in_invoicefw_file) > 0); 

} 
+1

Вы считали вместо команды 'comm (1)' unix? – jordanm

+0

jordanm - Я не дал мне взглянуть на страницы руководства на этом. Спасибо за совет. –

ответ

4

Типичный способ сделать это с помощью двух файлов:

my %items; 
while (<$file1>) { 
    $items{$_}++; 
} 
while (<$file2>) { 
    $items{$_}++; 
} 

Любой ключ в %items, который имеет значение 2 в обоих файлах; любой ключ со значением 1 находится только в одном файле.

Если вам нужно знать , в котором файла (-ов) появляется каждое значение, это может быть обобщено путем добавления разных номеров для каждого файла. например, если вы добавляете 100 для строк в первом файле, 10 для строк во втором файле и 1 для строк в третьем файле, то вы можете сразу увидеть, что ключ со значением 101 представляет строку, которая находится в первом и третьих файлов, но не во втором.

+1

Что Дэйв описывает с добавлением 100/10/1 в зависимости от файла, является формой использования битполей. Хорошая статья о perl и битовых полях находится здесь: http://www.effectiveperlprogramming.com/blog/714 – RickF

+0

Спасибо за ссылку, RickF! Реальное битовое поле, безусловно, более эффективно, и это то, что я, вероятно, использовал бы в The Real World. Основная причина, по которой я выбрал полномочия 10 в примере, состоит в том, что их легче увидеть визуально. –

+1

Единственная проблема с этим, добавив полномочия десяти, появляется, если у вас избыточные записи в списке. – RickF

Смежные вопросы