es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuál es el equivalente de grep -wf en awk?

Necesito buscar una lista de elementos (tratados como palabras exactas) en file1, como por ejemplo:

RYK
RELA
CCNB1
RXRG
CREB1
ACREB1
CREB1B

en un file2 con múltiples columnas, como por ejemplo:

KIAA0196 FAM21C
BIRC2 UBE2D2
BIRC3 UBE2D2
BIRC7 UBE2D2
XIAP UBE2D2
BRCA1 UBE2D2
CDK5R1 HSP90AA1
ICAM1 ITGB2
RYK CDK1
CSNK2A1 CDK1
NFKB1 RELA
CREB1 JUN
PPME1 NFKB1
ARID4A CDK1
ICT1 TFAM
EZH2 CDK1
CDK1 EZH2
CDK1 EZH2
CDK1 HIST1H1D
CDK1 EZH2
CDK1 EZH2
CDK1 EZH2
BCL6 E2F3
CDK1 CCNB1
MME PDIA5
PPP2R1B CDK1
PPP2R1A CDK1
PPP2R1A CDK1
PPP2R1B CDK1
NCOR2 RXRG
THRB RXRG
RARA RXRG
RARB RXRG
RARG RXRG
PPARD RXRG
HDAC5 CDK1
CDK1 RUNX1
CREBBP CREB1
SSSSS CREB1-C
dddd A-CREB1

con el fin de obtener como resultado todas las líneas que contengan al menos una palabra exacta en el archivo file1.

Normalmente utilizo grep -wf file1 file2 (-w para “coincidencias de palabras completas” y -f para “patrones desde archivo, uno por línea”), simple y aparentemente eficiente, y obtengo los siguientes resultados:

RYK CDK1
NFKB1 RELA
CREB1 JUN
CDK1 CCNB1
NCOR2 RXRG
THRB RXRG
RARA RXRG
RARB RXRG
RARG RXRG
PPARD RXRG
CREBBP CREB1
SSSSS CREB1-C
dddd A-CREB1

Un problema con -w es que (según el manual de grep) “la subcadena coincidente debe estar al principio de la línea o precedida por un carácter no constituyente de palabra. Del mismo modo, debe estar al final de la línea o seguida por un carácter no constituyente de palabra. Los caracteres constituyentes de palabra son letras, dígitos y el guion bajo”. Por lo tanto, en el ejemplo anterior, A-CREB1 y CREB1-C coinciden con CREB1, lo cual es un comportamiento indeseado.

Estaba buscando una solución con awk en una sola línea (bueno, aproximadamente, incluso unas pocas líneas servirían) para hacer lo mismo sin el problema mencionado anteriormente.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una posible solución utilizando awk es:

    awk 'BEGIN{IGNORECASE=1} FNR==NR{a[$1];next}{for(i=1;i<=NF;i++) {if($i in a){print; break}}}' archivo1 archivo2
    

    Explicación:

    • BEGIN{IGNORECASE=1}: establece la opción de ignorar mayúsculas y minúsculas para la coincidencia.
    • FNR==NR{a[$1];next}: procesa el primer archivo (archivo1) y guarda cada palabra en el array a.
    • {for(i=1;i<=NF;i++) {if($i in a){print; break}}}: para cada línea del segundo archivo (archivo2), verifica cada campo (NF) para ver si está en el array a. Si lo está, imprime la línea y rompe el bucle, de modo que se devuelva solo una coincidencia por línea.

    La salida debería ser:

    RYK CDK1
    NFKB1 RELA
    CREB1 JUN
    CDK1 CCNB1
    NCOR2 RXRG
    THRB RXRG
    RARA RXRG
    RARB RXRG
    RARG RXRG
    PPARD RXRG
    CREBBP CREB1
    

Comments are closed.