根據鍵比較兩個文件,在 Bash Shell 腳本中列印另一個文件中值的差異

根據鍵比較兩個文件,在 Bash Shell 腳本中列印另一個文件中值的差異

需要有關shell 腳本的幫助,我有2 個大約1.2 GB 資料的大文件,帶有鍵和值,我需要根據鍵比較兩個文件,並存儲第三個文件中的值與文件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 行,所以我想讓執行速度更快。這是在 shell 腳本中運行,使用#!/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 字典(hash) 。
資料檔:

$ 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

這是一個awk版本應該非常快。

適用於遵循要求的欄位模式 [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                    

相關內容