Procurando por linhas que estão em um arquivo, mas não em outro usando Unix e Awk [duplicado]

5

Eu tenho 2 arquivos com 7 campos e quero imprimir as linhas que estão presentes no arquivo1, mas não no arquivo2 com base no campo1 e no campo2.

Lógica: Quero imprimir todas as linhas, onde há uma coluna1 particular e uma coluna2. E nós não encontramos o conjunto de column1 e column2 no arquivo2. Exemplo: "sc2 / 10 10" este conjunto você não veria no arquivo 2, portanto é impresso como saída.

Arquivo1:

sc2/80         20      .        A       T         86       F=5;U=4
sc2/60         55      .        G       T         76       F=5;U=4
sc2/10         10      .        G       C         50       F=5;U=4
sc2/68         20      .        T       C         71       F=5;U=4
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

Arquivo2:

sc2/80         20      .        A       T         30       F=5;U=4 
sc2/60         55      .        T       T         77       F=5;U=4 
sc2/68         20      .        C       C         01       F=5;U=4
sc2/24         29      .        T       G         31       F=5;U=4
sc2/24         19      .        G       G         11       F=5;U=4
sc2/88         89      .        T       G         51       F=5;U=4

Resultado esperado:

sc2/10         10      .        G       C         50       F=5;U=4 
sc2/11         30      .        A       T         60       F=5;U=4 

Eu agradeceria sua ajuda.

    
por Namrata 21.08.2013 / 09:01

2 respostas

7

A menos que a entrada seja enorme, eu salvaria os pares file2 em um hash e usaria para ignorar as linhas em file1 . Por exemplo:

awk 'FNR == NR { h[$1,$2]; next }; !($1 SUBSEP $2 in h)' file2 file1

Saída:

sc2/10         10      .        G       C         50       F=5;U=4         
sc2/24         24      .        T       G         31       F=5;U=4
sc2/11         30      .        A       T         60       F=5;U=4

IIUC sc2/24 24 está corretamente incluído na saída.

Explicação

  • FNR == NR { h[$1,$2]; next } salva $1/$2 pairs no h hash (note que o acesso a um array por subscrito é suficiente para alocá-lo), mas somente a partir do primeiro arquivo de entrada ( file2 ). O comando next pula para o próximo registro.
  • ! ($1 SUBSEP $2 in h) é avaliado apenas para file1 e invocará o bloco padrão para linhas não contendo os pares $1/$2 . O bloco padrão é { print $0 } . (nota: evite usar !h[$1,$2] (o mesmo que !h[$1 SUBSEP $2] ) como alocaria)

O texto acima assume o valor de SUBSEP (geralmente o caractere ^\ ) não encontrado nos dois primeiros campos do arquivo.

    
por 21.08.2013 / 09:21
0

grep -Fvxf <remove> <all-lines>

  • funciona em arquivos não classificados
  • mantém o pedido
  • é POSIX

Exemplo:

cat <<EOF > A
b
1
a
0
01
b
1
EOF

cat <<EOF > B
0
1
EOF

grep -Fvxf B A

Saída:

b
a
01
b

Explicação:

  • -F : use strings literais em vez do padrão BRE
  • -x : considere apenas correspondências que correspondam à linha inteira
  • -v : imprimir sem correspondência
  • -f file : pegue padrões do arquivo fornecido

Esse método é mais lento em arquivos pré-classificados do que outros métodos, já que é mais geral. Se a velocidade também for importante, consulte: link

    
por 03.06.2016 / 09:58