Compare dois arquivos com o awk

1

Estou tentando comparar dois arquivos e imprimir a saída se eles corresponderem em alguns campos.

Arquivo1.txt:

bart:29482164591748
 apu:29482164591748
smithers:68468468468464
lisa:68468468468464
maggie:2348578903247548

Arquivo2.txt:

68468468468464:keyboard
68463894578424:user
29482164591748:computer

Eu gostaria dessa saída:

bart:29482164591748:computer
    
por Chris J 23.12.2015 / 12:01

3 respostas

6

Um clássico com join :

join -t: -1 2 -2 1 -o 2.1,1.1,1.2 <(sort -t: -k1,1 file1) <(sort -t: -k2,2 file2)
  • -t: especifica o cólon como separador.
  • O campo de junção -1 2 file1 é o segundo
  • O campo de associação -2 1 file2 é o primeiro
  • -o 2.1,1.1,1.2 do formato de saída.
  • <(...) : os dois arquivos devem ser classificados no campo de associação ( -k1,1 e -k2,2 ), -t: especifica o ponto-e-vírgula como separador para sort .
por 23.12.2015 / 12:19
3

com awk :

awk -F: 'NR==FNR{a[$1]=$2;next}a[$2]{print $1":"$2":"a[$2]}' file1 file2

Saída:

bart:29482164591748:computer
smithers:68468468468464:keyboard
lisa:68468468468464:keyboard

Após a edição da pergunta:

awk -F: 'NR==FNR{a[$2]=$1;next}a[$1]{print a[$1]":"$1":"$2}' file1 file2

Saída:

lisa:68468468468464:keyboard
bart:29482164591748:computer
    
por 23.12.2015 / 12:38
-1

Não usaria awk , mas usaria perl .

#!/usr/bin/env perl
use strict;
use warnings;

#open both files for reading
open( my $input1, '<', "file1.txt" ) or die $!;
open( my $input2, '<', "file2.txt" ) or die $!;

#read the key-values into a hash called lookup. 
my %lookup = do { local $/; <$input1> =~ m/(\d+):(\w+)/g; };

#iterate by line of second file
while ( <$input2> ) { 
    #trim trailing linefeeds
    chomp;
    #split current line on :
    my ( $user, $key ) = split /:/;
    #if exists in original lookup, display record 
    if ( $lookup{$key} ) {
        print join ( ":", $user, $key, $lookup{$key}),"\n";
    }
}

Eu recebo uma saída ligeiramente diferente - especificamente:

bart:29482164591748:computer
smithers:68468468468464:keyboard
lisa:68468468468464:keyboard

Não sei por que o segundo 2 não deve ser impresso com base nos valores-chave correspondentes.

Se você quer um forro que é basicamente o mesmo:

perl -F: -lane "print $k{$F[0]}.':'.$_ if $k{$F[0]}; $k{$F[1]}//=$F[0];" file2.txt file1.txt
    
por 23.12.2015 / 12:22