Usando datos CSV con awk

Estoy tratando de encontrar una manera de tomar los datos individuales de un archivo CSV y usarlos como una variable dentro de un grep o comando awk. Cualquiera parece apropiado, pero no estoy seguro de cómo decirle que lo haga correctamente.

Por ejemplo, tengo un conjunto de datos en formato TSV que se ve así:

ID Name Eye Color 1 Bill Blue 2 Sam Blue 3 Fred Brown 4 Joe Brown 5 Ted Blue 6 Bob Brown 

Este no es el conjunto de datos real, pero se comporta de la misma manera. Esta es la base de datos de enlace de proteínas completa, el TSV es de 300 MB con millones de entradas y docenas de columnas, así que no puedo incluir la cosa real.

Quiero hacer un archivo que contenga las filas con personas que tienen ojos azules, así que he creado un archivo CSV que se compone de " ID " columna, que en este caso se vería así:

1, 2, 5

Este CSV que contiene el " ID " se generó utilizando el " Grep " para buscar el término clave.

En última instancia, quiero un archivo TSV que se vea así: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Pero no puedo parecer averiguar cómo hacerlo. Puedo crearlo individualmente para cada entrada usando awk o grep e incluyendo el número de identificación como criterio, sin embargo, el CSV que estoy usando tiene 1200 entradas, así que me gustaría automatizar este proceso.

A continuación se muestra el código que producirá el resultado deseado para una sola entrada, pero quiero usar los números de identificación para buscar automáticamente.

El BindindDB_All.tsv es mi archivo fuente, con varios millones de entradas. Esto producirá un TSV llamado " new.tsv " y contiene la fila completa del archivo BindindDB_All.tsv donde el ID (en la columna 1) es igual a 66106.

awk "$1 == 66106" BindingDB_All.tsv >> new.tsv 

Me gustaría hacer algo como esto:

awk "$1 == ID.csv" BindingDB_All.tsv >> new.csv 

donde se leería cada ID, imprima la línea en new.csv, luego lea la siguiente ID y haga lo mismo.

El archivo CSV contiene 1200 términos de búsqueda, para compararlos con varios millones de posibilidades, cada uno con un ID único. I Necesito que SOLO busque la columna 1, ya que encontrará la ID dentro de otras variables es en cada fila.

Para resumir, necesito buscar en la columna 1 de la fila, compararlo con el primer número en mi archivo CSV y ver si coincide. Si no coincide, debe comprobar la siguiente fila en la columna 1 y así sucesivamente hasta que encuentre la coincidencia. Cuando encuentre la fila donde la columna 1 coincide con el primer punto de datos CSV, quiero que muestre la fila. Entonces quiero que se repita para la segunda entrada en el CSV, hasta que haya encontrado las 1200 filas.

¿Alguna idea? Suena como un problema de bucle, pero yo tampoco sé cómo hacer que eso funcione.

EDITAR:

Dado que la gente todavía parece estar dispuesta a ayudar, permítanme intentar responder las preguntas que se han publicado.

Aquí están las primeras 6 entradas de mis datos reales, que contienen números de identificación que se utilizarán como parámetros de búsqueda.

66106 66107 66108 66109 66110 50127715 

No hay nombres de columna, ni otros datos. Estos son valores que quiero buscar individualmente en un archivo diferente, un TSV. También me equivoqué con respecto al tamaño del TSV, tengo un TSV de 4 GB, que se comprime a 300 MB. El archivo contiene más entradas de las que cualquiera de mis programas le permite ver. A continuación se muestra un ejemplo de una sola entrada entre varios millones. NECESITO que se extraigan todos estos datos a la vez, por lo que recortarlos no es una opción.

50127715 CCCC (CCC) c1nc2N3 [C @ H] 4CCC [C @ H] 4N = C3N (C) C (= O) c2 [nH] 1 InChI = 1S / C18H27N5O / c1- 4-7-11 (8-5-2) 15-20-14-16 (21-15) 23-13-10-6-9-12 (13) 19-18 (23) 22 (3) 17 ( 14) 24 / h11-13H, 4-10H2,1-3H3, (H, 20,21) / t12-, 13 + / m1 / s1 CSRSQF SFDXYRFV-OLZOCXBDSA-N 50073697 5-metil-2- (1-propilbutil) – (6aR, 9aS) -3,4,5,8-tetrahidrociclopenta [4,5] imidazo [2,1-b] purin-4- uno :: CHEMBL280307 Fosfodiesterasa 1 Bos taurus 60 ChEMBL 10.1016 / s0960-894x (98) 00681-7 9990447 Ho, GD Silverman, L Bercovici, A Puchalski, C Tulshian, D Xia, Y Czarniecki, M Green, M Cleven, R Zhang, H Fawzi, A Schering-Plough Research Institute http://www.bindingdb.org/bind/chemsearch/marvin/MolStructure.jsp?monomerid=50073697 http://www.bindingdb.org/jsp/dbsearch/PrimarySearch_ki.jsp?energyterm=kJ/mole&tag=pol&polymerid=49000914&target=Phosphodiesterase+1&column=ki&startPg=0&Increment=50&submit=Search http://www.bindingdb.org/jsp/dbsearch/PrimarySearch_ki.jsp?energyterm=kJ/mole&tag=r21&monomerid=50073697&enzyme=Phosphodiesterase+1&column=ki&startPg=0&Increment=50&submit=Search 44272162 103967010 CHEMBL280307 ZINC28221715 1 MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS calcio / calmodulina dependiente de 3″ , 5″ fosfato de nucleótido cíclico odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

No estoy seguro de cómo hacer que esto se lea como un TSV dentro de este cuadro, pero 50127715 es la primera columna, la columna ID. Quiero tener mi archivo CSV inicial, que contenga los números de identificación de interés, busque en el TSV grande un número de identificación a la vez dentro de la primera columna. Si el número está contenido en la primera columna, quiero que escriba esa línea en un archivo y luego busque la siguiente ID. Quiero todos los resultados en un solo archivo.

Estoy seguro de que a lo largo de todos mis pasos para llegar aquí hay una manera más fácil de hacerlo, pero claramente no estoy seguro de cómo hacer esto más claro. Quiero que busque en el TSV grande " 66106 " dentro de la columna 1, y cuando encuentre la línea en la que escribir toda la línea un archivo. Luego, busque " 66107 " y, una vez que lo encuentre, lo agregará al mismo archivo. De esta manera tengo un solo archivo, puede ser un CSV o TSV, con 1200 entradas en lugar de varios millones.

Comentarios

  • ¿Por qué no simplemente analizar el TSV directamente? awk -F '\t' separará los campos de entrada por pestañas. Y de hecho, de forma predeterminada, awk separará los campos por espacios en blanco coniguos. Entonces, para obtener todas las personas de ojos azules (y preservar el encabezado), solo necesita awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Intenté ejecutar este comando en un archivo de muestra llamado " test.tsv ", con la misma entrada que la listada arriba, sin embargo, produjo una salida inusual. Simplemente reemplazó todos los colores de ojos con " azul " mientras que todo lo demás permaneció igual.
  • $3 = "Blue" debe ser $3 == "Blue". La primera es una asignación, la última es una comparación.
  • ¿Es esto un CSV o TSV?
  • Extraer la información sobre sus requisitos, una ruta de navegación a la vez, no es ' es un buen enfoque para obtener una buena solución. edita tu pregunta para proporcionar un ejemplo más representativo de lo que ' estás tratando de hacer. Incluya un archivo TSV, un archivo CSV y los archivos de salida esperados que espera dado como entrada. Asegúrese de cubrir todos sus casos de uso, p. Ej. si todas las coincidencias son contra valores en 1 columna o diferentes coincidencias en diferentes columnas, etc. Consulte Cómo preguntar .

Respuesta

$ awk -F"\t" "(NR==1) || ($3=="Blue")" file ID Name Eye Color 1 Bill Blue 2 Sam Blue 5 Ted Blue 

Sin embargo, parece que lo que realmente estás tratando de hacer es crear un archivo por ID que, asumiendo que los ID son únicos como en su ejemplo, sería:

awk -F"\t" "{ out="out_" $1 ".txt"; print > out; close(out) }" BindingDB_All.tsv 

o si desea que cada archivo de salida incluya el encabezado:

awk -F"\t" " NR==1 { hdr=$0; next } { out="out_" $1 ".txt"; print hdr ORS $0 > out; close(out) } " BindingDB_All.tsv 

Comentarios

  • Lo he editado para mayor claridad, pero realmente solo quiero 1 archivo que contenga esos nombres. Debido a que la naturaleza de los datos es enorme, intenté crear un conjunto de ejemplo con fines de demostración, pero ' soy nuevo en la programación, así que ' No estoy seguro de si ' estoy expresando correctamente lo que necesito.

Responder

Para cualquiera que pueda encontrar esto en el fu tura, tengo una solución. Lo primero que hice fue convertir el TSV a CSV usando:

sed "s/\t/,/g" filename_with_tabs > filename_with_commas.csv 

Luego, para buscar el código de mi archivo que estaba buscando es:

awk -F, "FNR==NR {h[$1] = $0; next} {print $0,h[$1]}" file1 file2 > new_file.csv 

Esto buscará en la primera columna el texto contenido en un CSV separado. En este caso, " file1 " es el archivo para buscar y " file2 " contiene las cadenas para buscar. Ambos archivos están en formato CSV.

Esto produjo un archivo CSV separado que contenía todas las líneas dentro del archivo1 que tenía un cierto ID en la columna 1 que coincide con uno de los ID contenidos en el archivo2.

Espero que eso ayude alguien algún día, porque esto me ha destrozado la cabeza durante semanas. Ni siquiera obtuve la solución, mi jefe tuvo que mostrármelo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *