Eu tenho um pequeno trecho de um arquivo com o qual estou trabalhando:
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000032737 ENSDARP00000049290
ENSDARG00000061051 ENSDARP00000081062
ENSDARG00000061051
ENSDARG00000061051 ENSDARP00000129708
Quero imprimir apenas a primeira instância de cada valor exclusivo na primeira coluna e o valor correspondente na segunda coluna, então minha saída desejada seria:
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
Existe uma maneira simples de fazer isso com awk ou uniq ou algo semelhante?
Qualquer ajuda seria apreciada.
Responder1
POSIX AWK:
m1[$1] == 0 {
m1[$1] = 1
print
}
Para cada linha:
- veja se a primeira coluna existe no "banco de dados"
- caso contrário, adicione ao "banco de dados" e imprima a linha inteira
Responder2
$ sort -s -k1,1 -u file
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
Isso classifica o arquivo com base apenas na primeira coluna. Ao fazer isso, ignora as linhas cuja primeira coluna já foi vista.
A maioria das implementações de sort
possui uma opção não padrão -s
(usada no comando acima) que garante que estará usando um algoritmo de classificação "estável". Um algoritmo de classificação estável não altera a ordem das entradas que possuem chaves idênticas (primeira coluna no seu caso).
Observe, entretanto, que a transcrição mais longa (com a qual Ensembl e Havana concordam 100%) para oENSDARG00000032737gene é ENSDART00000049291, que codifica ENSDARP00000049290, não ENSDARP00000120731. Mas isso não é da minha conta.
Responder3
Esta solução idiomática funcionará de forma robusta usando qualquer awk em qualquer shell em cada caixa UNIX:
$ awk '!seen[$1]++' file
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062
Responder4
Melhores soluções já fornecidas apenas postando minha tentativa
for i in `awk '{if(!seen[$1]++)print $1}' filename`; do sed -n '/'$i'/{p;q}' filename; done
saída
ENSDARG00000032737 ENSDARP00000120731
ENSDARG00000061051 ENSDARP00000081062