키를 기준으로 두 파일을 비교하고 Bash 쉘 스크립트에서 다른 파일의 값 차이를 인쇄합니다.

키를 기준으로 두 파일을 비교하고 Bash 쉘 스크립트에서 다른 파일의 값 차이를 인쇄합니다.

셸 스크립트에 대한 도움이 필요합니다. 키와 값이 포함된 약 1.2GB의 데이터가 포함된 2개의 대용량 파일이 있습니다. 키를 기반으로 두 파일을 비교하고 파일 1의 고유 값과 함께 세 번째 파일에 값을 저장해야 합니다. 차이점,

파일 1:

test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet

파일 2:

test1 polo;angus
test2 mike
test4 bob;janet

file1과 file2의 처음 두 열을 비교하고(처음 두 열에서 file2의 전체 내용을 검색) 일치하는 경우 값의 차이를 인쇄하고 싶습니다. 그런 다음 파일 1의 두 번째 줄을 검색합니다. 파일 1의 고유 키도 인쇄되어야 합니다.

예상 출력:

test1 marco
test2 zen;liza
test3 tom;harry;alan
test4 june

내 파일은 약 100,000줄을 포함하는 대용량이므로 실행 속도를 더 빠르게 만들고 싶습니다. 이는 #!/usr/bin/env bash. 다음 예를 사용하여 쉘 스크립트에서 실행됩니다 .

1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule 343323H;343434311H;454656556H;343343432H 

1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule이것은 키( )와 값( 343323H;343434311H;454656556H;343343432H) 이 포함된 간단한 텍스트 파일입니다 .

파일 2는 항상 파일 1의 하위 집합이며 파일 2에 존재하지 않는 값(키의 경우)과 파일 1에 고유한 값만 찾습니다.

답변1

Perl 스크립트를 사용하십시오:

검색 중이라고 가정해 보겠습니다.파일 2는 파일 1을 기반으로 합니다.그 반대는 사실이 아닙니다. file2를 기반으로 file1을 검색하려면 다음을 수행해야 합니다.다른 for 루프 추가file2 사전(해시)의 경우.
데이터 파일:

$ cat file1.txt 
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet

$ cat file2.txt 
test1 polo;angus
test2 mike
test4 bob;janet

스크립트:

#!/usr/bin/perl

use warnings;
use strict;

my $file1=$ARGV[0];
my $file2=$ARGV[1];
my %dict1;  #Stores file1 unique key and value pairs in this dictionary ( HASH in perl )
my %dict2;  #Stores file2 unique key and value pairs in this dictionary ( HASH in perl )
my %output;     #This is output dictionary after processing all the data to print it out

open(F1,'<',$file1) or die "File not found $file1";
open(F2,'<',$file2) or die "File not found $file2";

#Store both file's contents in %dict1 and %dict2 respectively 
while(<F1>)
{
    my ($key,$value) = split(/\s+/,$_);
    $dict1{$key} = $value;
}

while(<F2>)
{
    my ($key,$value) = split(/\s+/,$_);
    $dict2{$key} = $value;
}

#Get the unique(difference) value from file2 based in the values in file1

foreach my $k ( keys %dict1 )
{
    if ( defined $dict2{$k} )
    {
        my @dict1values=split(";",$dict1{$k});
        my @dict2values=split(";",$dict2{$k});
        foreach (@dict1values)
        {
            if (   $dict2{$k} !~ /[;]*?$_[;]*?/) {

                $output{$k} .=$_.";";

             }
        }
    } else { 
        $output{$k}=$dict1{$k};
    }
}

foreach my $ke (sort(keys(%output)))
{
    print "$ke $output{$ke}\n" if ( defined($output{$ke}) );
}  

산출:

$ ./testing.pl file1.txt file2.txt 
test1 marco;
test2 zen;liza;
test3 tom;harry;alan
test4 june;

답변2

이것은버전이 매우 빨라야 합니다.

요청된 필드 패턴 [string:key][space|";"][string][space|";"] 등을 따르는 모든 항목에 적용됩니다.

$ cat file1;echo "";cat file2
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet

test1 polo;angus
test2 mike
test4 bob;janet            
$ awk -F '[ ;]' '
  NR==FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
  NR!=FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
  END{ for(i in k){
         if(k[i]==1){
           split(i,arr_i,SUBSEP); 
           k_e[arr_i[1]]=k_e[arr_i[1]]""arr_i[2]";"
         }
       }
       for(i in k_e){
         print i" "k_e[i]
       }
  }' file1 file2 | sort | sed 's/.$//'

test1 marco
test2 liza;zen
test3 harry;alan;tom
test4 june                    

관련 정보