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.

¿Cómo se realiza la búsqueda con grep/awk desde una columna en un archivo?

Tengo un archivo de IDs llamado IDs_list.txt que quiero usar para extraer información de un segundo archivo que tiene cientos de IDs, muchos de los cuales no están en mi archivo específico IDs_list.txt.

He probado combinaciones de if y grep pero mis resultados siguen saliendo vacíos.

Aquí tienes un ejemplo de lo que estoy intentando hacer y lo que he hecho:

cat IDS_list.txt | head -n 4
24
43
56
69

cat sample1.txt | head -n 4
NODE_1_length_148512_cov_24.5066,gi|573017271|gb|CP006568.1|,148512,4513140,8,7289,86.545,0.0,13461,24,madeup species 1
NODE_2_length_122550_cov_25.719,gi|84778498|dbj|AP008232.1|,122550,4171146,13,12690,93.693,0.0,23435,244,madeup species 2
NODE_3_length_103385_cov_25.9802,gi|84778498|dbj|AP008232.1|,103385,4171146,6,4243,88.782,0.0,7836,43,madeup species 3
NODE_4_length_101672_cov_25.6536,gi|84778498|dbj|AP008232.1|,101672,4171146,7,4139,86.799,0.0,7644,955,long name here

Los IDs están en la décima columna.

Necesitaré extraer todas las líneas donde los IDs se encuentren en IDs_list.txt.

Entonces mi resultado debería ser:

NODE_1_length_148512_cov_24.5066,gi|573017271|gb|CP006568.1|,148512,4513140,8,7289,86.545,0.0,13461,24,madeup species 1
NODE_3_length_103385_cov_25.9802,gi|84778498|dbj|AP008232.1|,103385,4171146,6,4243,88.782,0.0,7836,43,madeup species 3

He intentado lo siguiente:

for file in sample?.txt; do awk ‘FNR==NR{arr[$0];next} ($10 in arr)’ IDs_list.txt $file; done

No sale nada. Este ejemplo lo saqué de otra pregunta de stack overflow.

for i in $(cat IDs_list.txt); do awk -F”,” ‘$10 == $i’ sample1.txt; done

Pero esto imprimirá una sola salida tantas veces porque estoy iterando sobre los IDs_list.txt línea por línea, por lo que no es lo que quiero. Obtendré la primera línea de salida tal vez cientos de veces porque mi archivo IDs_list.txt tiene cientos de IDs.

Luego intenté grep con awk pero eso tampoco funcionó. Mi sintaxis está mal.

for file in sample?.txt; do for i in $(cat IDs_list.txt); do grep -w ‘$i’ $file; done; done

No se produce ninguna salida aquí. Mi lógica es que para cada archivo de muestra, quiero usar grep en las líneas que contienen el ID que se encuentra en el archivo IDs_list.txt. Sin embargo, no me gusta no llamar a la columna específica 10 porque los IDs a veces pueden aparecer en otras columnas que no son realmente IDs.

¿Alguna forma elegante de hacer esto en un bucle for con grep o awk o ambos de alguna manera?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para extraer las líneas del segundo archivo que tienen IDs que figuran en el archivo IDs_list.txt, puedes usar grep con la opción -f para leer la lista de patrones desde un archivo. Luego, puedes usar awk para asegurarte de que solo se impriman las líneas que tengan IDs coincidentes en la décima columna.

    Aquí tienes un ejemplo de comando que debería lograr el resultado deseado:

    grep -wf IDs_list.txt sample1.txt | awk -F ',' '{
        if ($10 in ids) print $0;
        else ids[$10] = 1
    }'
    

    Vamos a desglosarlo:

    • grep -wf IDs_list.txt sample1.txt busca las líneas en sample1.txt que coinciden con alguno de los patrones en IDs_list.txt.
    • La salida de grep se pasa como entrada a awk, que utiliza la coma (,) como separador de campos (-F ',').
    • La declaración if dentro de awk verifica si el valor en la décima columna (representado por $10) ya se ha impreso. Si es así, se omitirá la línea. Si no, se imprimirá la línea y se agregará el valor de la décima columna al arreglo ids para asegurarse de que no se imprima nuevamente.
    • Finalmente, la salida de awk es el conjunto deseado de líneas.

    Este comando debería ser capaz de manejar grandes cantidades de IDs y líneas, sin hacer múltiples recorridos de los datos.

Comments are closed.