Você pode usar awk
. Coloque o seguinte em um script, script.awk
:
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Agora execute assim:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
O script funciona da seguinte maneira. Este bloco cria três matrizes, f1
, f1_c14
e f1_c5
. f1
contém todas as linhas do arquivo1 em uma matriz, indexadas usando o conteúdo das colunas 1, 2 e & 4 do arquivo1. f1_c14
é outro array com o mesmo índice (conteúdo de 1, 2 e 4) e um valor de 1
. O terceiro array usa o mesmo índice do primeiro 2, com o valor da quinta coluna do arquivo1.
FNR == NR {
f1[$1,$2,$4] = $0
f1_c14[$1,$2,$4] = 1
f1_c5[$1,$2,$4] = $5
next
}
O próximo bloco é responsável por imprimir linhas do primeiro arquivo, file1
sob as condições que as colunas 1, 2 e & 4 corresponde as colunas de file2
, AND e imprimirá a linha de file1
se as 5 colunas de file1
e file2
não corresponderem.
f1_c14[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print f1[$1,$2,$4];
}
O terceiro bloco é responsável por imprimir a linha associada de file2
, há uma linha correspondente na matriz f1
para as colunas 1, 2, & file2
4. Novamente, ele só imprime se as 5a colunas não corresponderem.
f1[$1,$2,$4] {
if ($5 != f1_c5[$1,$2,$4]) print $0;
}
Exemplo
Executando o script acima da seguinte forma:
$ awk -f script.awk file1 file2
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Você pode usar o comando column
para limpar um pouco a saída:
$ awk -f script.awk file1 file2 | column -t
sc2/80 20 . A T 86 PASS N=2 F=5;U=4
sc2/80 20 . A C 80 PASS N=2 F=5;U=4
sc2/60 55 . G T 76 PASS N=2 F=5;U=4
sc2/60 55 . G C 72 PASS N=2 F=5;U=4
Como funciona?
FNR == NR Isso faz uso da capacidade de awk
de fazer um loop pelos arquivos de uma maneira específica. Aqui estamos nós percorrendo os arquivos e quando estamos em uma linha do primeiro arquivo, file
, queremos executar um determinado bloco de código nesta linha a partir de file1
.
Este exemplo mostra o que o FNR == NR
está fazendo quando damos 2 arquivos simulados. Um tem 4 linhas enquanto o outro tem 5 linhas:
$ awk 'BEGIN {print "NR\tFNR\tline"} {print NR"\t"FNR"\t"$0}' \
<(seq 1 4) <(seq 1 5)
NR FNR line
1 1 1
2 2 2
3 3 3
4 4 4
5 1 1
6 2 2
7 3 3
8 4 4
9 5 5
outros blocos
Os outros blocos, f1_c14[$1,$2,$4]
AND f1[$1,$2,$4]
, só são executados quando os valores desses elementos da matriz têm um valor.