Compare 2 arquivos e armazene a saída como file1_value, file2_value, Match / NoMatch

1

Eu tenho 2 arquivos,

arquivo1 - >

1
2
2
3
5

arquivo2 - >

1
3
2
6

Eu quero que a saída seja armazenada em um terceiro arquivo chamado file3 como

1,1,Match
2,2,Match
2,,NoMatch
3,3,Match
5,,NoMatch
 ,6,NoMatch

Eu tentei,

sort file1 > file1sorted.txt
sort file2 > file2sorted.txt

# Combine the sorted files with a comma and store it in a new file
paste -d ',' file1sorted.txt file2sorted.txt   > mergedsortedfile.txt

# Compare the columns and store the result in a new file
awk -F',' '{print $1 == $2 ? "MATCH" : "NO MATCH"}' mergedsortedfile.txt > result.txt

# Merge the result file with the already existing merged file
paste -d ', ' mergedsortedfile.txt result.txt > final_result.txt

O resultado aparece assim,

1,1,MATCH
2,2,MATCH
2,3,NO MATCH
3,6,NO MATCH
5,,NO MATCH
    
por akilesh raj 06.02.2017 / 06:18

2 respostas

2

Usando comm nos dados classificados:

$  comm <( sort -n file1 ) <( sort -n file2 )
                1
                2
2
                3
5
        6

Esta saída é delimitada por tabulações. Podemos marcar tudo nas colunas 1 e 2 como "NoMatch" e na coluna 3 como "Match" com awk :

$ comm  <( sort -n file1 ) <( sort -n file2 ) |
  awk -F$'\t' 'BEGIN { OFS="," } $3 { print $3, $3, "Match"; next } { print $1, $2, "NoMatch" }'
1,1,Match
2,2,Match
2,,NoMatch
3,3,Match
5,,NoMatch
,6,NoMatch

O script awk lerá a entrada delimitada por tabulação ( -F$'\t' ) e usará vírgulas para o delimitador do campo de saída ( OFS="," ). Se houver algo no campo 3, ele emitirá duas vezes com Match no terceiro campo e continuará com a próxima linha. Caso contrário, ele exibirá os campos 1 e 2 da entrada junto com NoMatch no terceiro campo.

    
por 06.02.2017 / 11:35
0

Salve este script perl como arquivo xxx e execute-o com perl xxx file1 file2

#!/usr/bin/perl

# save the first two files, the <> slurp clears @ARGV
($f1,$f2) = @ARGV;

# build a hash of hash of lines from all files,
# with the filename as key
do { chomp; push @{$hash{$ARGV}}, $_ } while <>;

# compare every line until both are empty
# the hash slice is a short expression for
# $a = $hash{$f1}->[$x]
# $b = $hash{$f2}->[$x]
for ($x=0;;$x++) {
   ($a,$b) = map { $$_[$x] } @hash{$f1,$f2};
   last unless $a or $b;
   printf "%s,%s,%s\n", $a, $b, $a eq $b ? 'Match' : 'NoMatch';
}
    
por 06.02.2017 / 10:57