2013-12-21 1 views
-1

У меня есть эти 2 текстовых файла, и я хотел бы найти какое-либо несоответствие для 2-го столбца между файлами. Несоответствие, которое должно быть идентифицировано, основано на типе F ,P and N независимо от того, какие строки они встречаются. У меня 1F, 3P в первом файле, а 2P, 1N и 1F во втором файле. При сравнении, оба файла должны иметь одинаковое появление типов 1F, 3P и 1N.Найти несоответствие 2-го столбца между 2 текстовыми файлами

Текст1

f0x11 F 
f0x34 P 
drx99 
dex67 P 
edx43 P 
sdx33 

Текст2

1 P 
2 N 
4 
5 F 
6 
7 P 

Ожидаемый результат:

Text 1 has missing type of N 
Text 2 has missing type of P 

То, что я пытался до сих пор не дает желаемых результатов.

код:

use strict; 
my %ref_data; 
my %ref_data2; 
open my $fh, '<', 'Text1' or die "Could not open file to read:$!"; 
while (<$fh>) { 
    chomp; 
    my ($res, $type) = split; 
    if (defined $type){ 
      $ref_data{$type} = "$type"; 
      }   
} 
our ($data,$data2); 
open $fh, '<', 'Text2' or die "Could not open file to read:$!"; 
while (<$fh>) { 
    chomp; 
my ($res, $type) = split; 
    if (defined $type){ 
       $ref_data2{$type}= "$type"; 
       $data2= $ref_data2{$type}; 
       $data = $ref_data{$type}; 
       print "File 2 has missing type of $type\n" unless $data; 
     } 
    } 
foreach ($data){ 
print "File 1 has missing type of $_\n" if $data ne $data2; 
} 
+0

Просьба посоветуйте мне. Заранее спасибо. – annel

+1

Я не вижу, как вы получите ожидаемый результат выше от ваших входных данных. Оба ваших входных файла имеют один F, только на разных строках: почему ваш вывод говорит, что только один из них имеет «отсутствующий тип F»? –

+0

@llmari это была ошибка типографии. – annel

ответ

1

Я переработан код, где вы, кажется, дублирует такое же поведение.

Выход не специфицирован, но должен быть достаточно ясным, чтобы вы могли понять и закончить себя.

Я добавил close $fh; и use warnings;, а

#!/usr/bin/perl 

use strict; 
use warnings; 

#run 
my %max; # hash of combined data 
my $file_data_1 = parse_file_into_hash("text1", \%max); 
my $file_data_2 = parse_file_into_hash("text2", \%max); 
diff_hashes(\%max, $file_data_1, $file_data_2); 

# diff_hashes($max, $h1, $h2) 
# 
# diffs 2 hash refs against a combined $max hash and prints results 
sub diff_hashes { 
    my ($max, $h1, $h2) = @_; 

    # TODO - do all the comparisios and some error checking (if keys exist etc...) here 
    for my $key (keys %$max) { 
     print "max/combined: $key = $max->{$key}\n"; 

     my $h1_print = exists $h1->{$key} ? $h1->{$key} : "0"; 
     my $h2_print = exists $h2->{$key} ? $h2->{$key} : "0"; 

     print "h1: $key = $h1_print\n"; 
     print "h2: $key = $h2_print\n"; 
    } 
} 

# parse_file_into_hash($file, $max) 
# 
# $max is a hash reference (passed by reference) so you can count occurences over 
# multiple files... 
# returns reference of hash ($line_number => $data_value) 
sub parse_file_into_hash { 
    my ($file, $max) = @_; 
    my %ref_data; 

    open my $fh, '<', $file or die "Could not open file to read:$!"; 
    while (my $line = <$fh>) { 
     chomp $line; 
     my ($res, $type) = split /\s+/, $line; 

     if ($type) { 
      $ref_data{$type}++; 

      if (!exists $max->{$type} || $ref_data{$type} > $max->{$type}) { 
       $max->{$type} = $ref_data{$type}; 
      } 
     } 
    } 
    close $fh; 

    return \%ref_data; 
} 

Выходной побежал против ваших примеров файлов:

$ ./example.pl 
max/combined: F = 1 
h1: F = 1 
h2: F = 1 
max/combined: N = 1 
h1: N = 0 
h2: N = 1 
max/combined: P = 3 
h1: P = 3 
h2: P = 2 
+0

Спасибо за быстрый ответ. Чтобы было ясно, я хотел бы проверить, соответствует ли тип во втором столбце текста 1 типу в другом файле. У меня есть 1F, 3P в первом файле, в то время как второй файл 2P, 1N и 1F'in. При сравнении оба файла должны иметь одинаковое количество типов «1F, 3P и 1N» независимо от порядка или строки.Поэтому в сообщении «Файл 1 отсутствует тип N, P» и «Файл 2 имеет отсутствующий тип P». – annel

+0

@annel - Я изменил свой пример, чтобы сделать то, что вы хотите. Я не делал вывод так, как вам хочется. Вы должны быть в состоянии сделать эту часть самостоятельно. Мне это кажется домашним заданием ... – chrsblck

3

Вы кажетесь хотите отслеживать, сколько раз значения в колонке 2 происходит в каждом файле - например, в комментарии, который вы пишете: «У меня 1F, 3P в первом файле, а 2P, 1N и 1Fin второй файл». Если это так, вам нужна лучшая структура данных.

В частности, тот, который считает вхождения значений в столбце 2, и вам нужно, чтобы эти подсчеты отслеживались отдельно для каждого файла. Это говорит о хэш-хешах.

use strict; 
use warnings; 

# Example usage: 
# perl YOUR_SCRIPT.pl a.txt b.txt 
my @files = @ARGV; 

# Count the values in Column 2, organizing the tallies like this: 
# $tallies{COL_2}{FILE_NAME} = N 
my %tallies; 
while (<>) { 
    my @cols = split; 
    $tallies{$cols[1]}{$ARGV} ++ if @cols > 1; 
} 

# Print discrepancies. 
for my $c2 (keys %tallies) { 
    my @t = map { $tallies{$c2}{$_} || 0 } @files; 
    next if $t[0] == $t[1]; 
    print "$c2: $files[0] has $t[0]; $files[1] has $t[1]\n"; 
} 

Пример вывод:

N: a.txt has 0; b.txt has 1 
P: a.txt has 3; b.txt has 2 

Также стоит отметить: этот код не должен открывать любые файлы в явном виде, а имена файлов не жестко закодированы в программе. Вместо этого мы передаем имена входных файлов в качестве аргументов командной строки, получаем эти аргументы через @ARGV, обрабатываем строки в этих файлах через <> и знаем, какой файл мы сейчас обрабатываем через $ARGV.

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