2013-12-21 4 views
-1

두 개의 텍스트 파일이 있는데 두 번째 열의 파일간에 불일치를 찾고 싶습니다. 식별 될 불일치는 발생하는 행에 관계없이 유형이 F ,P and N 인 것을 기]으로합니다. 첫 번째 파일에는 1F, 3P가 있고 두 번째 파일에는 2P, 1N 및 1F가 있습니다. 비교할 때 두 파일 모두 1F, 3P 및 1N 유형의 동일한 발생이 있어야합니다.두 번째 텍스트 파일 사이의 두 번째 열에서 불일치 찾기

텍스트 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'이 있습니다. 비교할 때 두 파일의 순서 또는 행과 관계없이 두 파일의 유형이 '1F, 3P 및 1N'이어야합니다.따라서 '파일 1에는 N, P 유형이 누락되어 있으며'파일 2에는 P 유형이 없습니다 '라는 메시지가 표시됩니다. – annel

+0

@ channel - 원하는 것을하기 위해 예제를 변경했습니다. 나는 당신이 원하는대로 출력을 해오지 못했습니다. 이 부분을 스스로 할 수 있어야합니다. 이건 내 숙제처럼 보입니다 ... – chrsblck

3

예를 들어, "첫 번째 파일에는 1F, 3P, 두 번째 파일에는 2P, 1N 및 1Fin 두 번째 파일"이 있습니다. 이 경우 더 나은 데이터 구조이 필요합니다.

특히 두 번째 열의 값 발생 횟수를 계산하는 것이므로 각 파일에 대해 개별적으로 추적해야합니다. 그것은 해시 해시를 제안합니다.

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으로 알 수 있습니다.