Comparando arquivos linha por linha em awk com delimitador

4

arquivo1:

abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator

arquivo2:

abc|123|check
def|456|map
ijk|789|equator
lmn|101112|globe

SAÍDA ESPERADA:

ijk|789|equator
lmn|101112|globe

Script awk atual:

awk 'BEGIN{OFS=FS="|"} NR==FNR{a[$3]=$3;next}!($3 in a)' file1 file2

Isso faz comparação com base no conteúdo da matriz. Como comparar linha por linha e imprimir apenas os resultados.

    
por user1502952 23.09.2013 / 09:18

3 respostas

5

Se eu entendi corretamente, você deseja imprimir uma linha do arquivo2 se o 3º campo for diferente da entrada correspondente no arquivo1. Se assim for, isso deve ser feito:

awk 'BEGIN{FS="|"} NR==FNR{a[$1,$2]=$3;next}(a[$1,$2]!=$3)' file1  file2

O seu não estava funcionando porque você estava aceitando $3 , pois a chave do array a e $3 não é única (tanto equator quanto globe estão presentes nos dois arquivos).

Concordo com @drewbenn que tanto grep quanto join são mais simples para esse caso em particular, mas aqui está uma maneira Perl de fazer a mesma coisa:

perl -laF'\|' -ne '($k{$F[0].",".$F[1]}||=$F[2]) eq $F[2]||print;' file1  file2
    
por 23.09.2013 / 11:30
5

Acho que você deseja usar join (ou grep -f ). Mas se você precisar usar o awk:

echo | awk '{system("join -v 2 file1 file2")}'

que é apenas um front-end do awk para join -v 2 file1 file2 . Da mesma forma, é claro, você pode usar grep -v -f file1 file2 .

    
por 23.09.2013 / 09:35
5

comm é a ferramenta real para este trabalho:

comm -13 file1 file2
ijk|789|equator
lmn|101112|globe

Se os arquivos de entrada ainda não estiverem classificados:

comm -13 <(sort file1) <(sort file2)
    
por 23.09.2013 / 14:59