Usando o awk para comparar arquivos e combinar saída de ambos os arquivos?

4

Estou tentando comparar dois arquivos usando awk e gostaria de imprimir dados de ambos os arquivos como saída. Os arquivos que estou comparando são os seguintes.

Arquivo1:

gene             feature id            fc         
a                gene                 MSTRG.1.1           
b                gene                 MSTRG.1.2   
c                gene                 MSTRG.2.1 
d                gene                 MSTRG.3.1   

Arquivo2:

MSTRG.1.1       ALLMI        
MSTRG.3.1       COTJA   
MSTRG.4.1       SORCY 

Eu tenho usado o seguinte comando:

$ awk -F '\t' 'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $1}' File2 File1

Eu gostaria que a saída fosse:

a ALLMI
c COTJA
d SORCY,

No entanto, atualmente só recebo o seguinte como saída:

a    
c    
d

Ambos os arquivos são delimitados por tabulações, por isso não sei por que meu comando não está funcionando?

    
por Josh 02.08.2018 / 23:19

3 respostas

8

solução awk

Que tal isso. Não fornece a saída exata que você oferece, mas não tenho certeza de por que d SORCY seria impresso como d is MSTRG3.1 , que é COTJA .

De qualquer forma, aqui vai. Starter-for-dez. Funciona bem no GNU Awk v4.0.2.

$ awk 'NR==FNR{a[$1]=$2}NR!=FNR&&FNR>1&&a[$3]{print $1,a[$3]}' file2 file1
a ALLMI
d COTJA
$

Se NR for igual a FNR, estaremos no primeiro arquivo, então preencha o array.

Se NR não é o mesmo que FNR, estamos no 2º arquivo, então uma vez que passamos do primeiro registro deste arquivo (cabeçalho), e se o campo 3 existe no array, imprima-o. / p>

solução awk "golfada"

Código menos legível, mas mais curto.

awk 'NR==FNR{a[$1]=$2}a[$3]{print$1,a[$3]}' file{2,1}

associa a solução

Como alternativa, se você não for específico em relação à necessidade de usar awk , use apenas join .

$ join -1 3 -2 1 -o "1.1 2.2" file1 file2
a ALLMI
d COTJA
$

Junte os arquivos usando o campo 3 do arquivo 1 ( -1 3 ) e o campo 1 do arquivo 2 ( -2 1 ). Em seguida, imprima o campo 1 do arquivo1 e o campo2 do arquivo2. Bingo.

    
por 02.08.2018 / 23:44
3

Tente isso,

 awk  'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $1"\t"$3}'  file2 file1
  • não precisamos de \t como um delimitador.
  • precisamos imprimir primeiro e terceiro campo como sua exigência.
por 02.08.2018 / 23:47
3

Seu código,

awk -F '\t' 'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $1}' File2 File1

nunca produziria duas colunas, pois o print no final só gera a primeira coluna de File1 .

Você está quase lá embora. Você precisa fazer um ajuste minúsculo, que é realmente produzir o campo ausente:

awk -F '\t' 'BEGIN{OFS=FS} NR==FNR {a[$1]=$1; next} $3 in a {print $3, $1}' File2 File1
                                                                   ^^^
                                                                 add this

Executar isso nos seus dados deve produzir

MSTRG.1.1 a
MSTRG.3.1 d

Para grandes conjuntos de dados, consulte a solução da steve que é mais eficiente em termos de memória.

    
por 03.08.2018 / 08:54