Bruke CSV-data med awk

Jeg prøver å finne en måte å ta individuelle data fra en CSV-fil, og bruke den som en variabel i en grep eller vanskelig kommando. Enten virker passende, men jeg er ikke sikker på hvordan jeg skal fortelle den å gjøre dette på riktig måte.

For eksempel har jeg et datasett i TSV-format som ser slik ut:

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

Dette er ikke selve datasettet, men oppfører seg på samme måte. Dette er hele proteinbindingsdatabasen, TSV er 300 MB med millioner av oppføringer og dusinvis av kolonner, så jeg kan ikke rent inkluderer den virkelige tingen.

Jeg vil lage en fil som inneholder radene med enkeltpersoner som har blå øye, så jeg har opprettet en CSV-fil som består av " ID " kolonne, som i dette tilfellet vil se slik ut:

1, 2, 5

Denne CSV-en som inneholder " ID " ble generert ved hjelp av " Grep " kommando for å søke etter nøkkelordet.

Jeg vil til slutt ha en TSV-fil som ser slik ut: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Men jeg kan ikke virke å finne ut hvordan gjøre det. Jeg kan lage den individuelt for hver oppføring ved hjelp av awk eller grep, og inkluderer ID-nummeret som et kriterium, men CSV-en jeg bruker har 1200 oppføringer, så jeg vil automatisere denne prosessen.

Nedenfor er koden som vil gi ønsket resultat for en enkelt oppføring, men jeg vil bruke ID-numrene til å søke automatisk.

BindindDB_All.tsv er kildefilen min, med flere millioner oppføringer. Dette vil gi en TSV kalt " new.tsv " og inneholder hele raden i BindindDB_All.tsv-filen der ID (i kolonne 1) tilsvarer 66106.

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

Jeg vil gjerne gjøre noe slikt:

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

der den vil lese hver ID, skriv ut linjen til new.csv, les deretter neste ID og gjør det samme.

CSV-filen inneholder 1200 søkeord, som kan sammenlignes med flere millioner muligheter hver med en unik ID. I trenger det å KUN søke i kolonne 1, da den finner ID-en i andre variabler es i hver rad.

For å oppsummere trenger jeg det for å se i kolonne 1 på raden, sammenligne det med det første tallet i CSV-filen min, og se om det samsvarer. Hvis det ikke er en kamp, må den sjekke neste rad i kolonne 1 og så videre til den finner samsvaret. Når den finner raden der kolonne 1 samsvarer med CSV-datapunktet, vil jeg at det skal sendes ut raden. Så vil jeg at den skal gjenta for andre oppføring i CSV, til den har funnet alle 1200 radene.

Noen ideer? Det høres ut som et loopproblem, men jeg vet ikke hvordan jeg skal få det til å fungere heller.

REDIGER:

Siden folk fremdeles ser ut til å være villige til å hjelpe, la meg prøve å svare på spørsmålene som er lagt ut.

Her er de første 6 oppføringene av de virkelige dataene mine, som inneholder ID-nummer som vil bli brukt som søkeparametere.

66106 66107 66108 66109 66110 50127715 

Det er ingen kolonnenavn, ingen andre data. Dette er verdier som jeg ønsker å søke etter individuelt i en annen fil, en TSV. Jeg har også feiltalt angående TSV-størrelsen, jeg har en 4 GB TSV, som komprimerer til 300 MB. Filen inneholder flere oppføringer enn noen av programmene mine tillater den å se på. Nedenfor er et eksempel på en enkelt oppføring av flere millioner. Jeg TRENGER at alle disse dataene blir trukket samtidig, så beskjæring er ikke en alternativ.

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-metyl-2- (1-propylbutyl) – (6aR, 9aS) -3,4,5,8-tetrahydrosyklopenta [4,5] imidazo [2,1-b] purin-4- en :: CHEMBL280307 Fosfodiesterase 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 en MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS kalsium / kalmodulin-avhengige 3″ , 5″ -syklisk nukleotidfosf odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Jeg er ikke sikker på hvordan jeg skal få dette til å lese som en TSV i denne boksen, men 50127715 er den første kolonnen, ID-kolonnen. Jeg ønsker å ha den første CSV-filen min, som inneholder ID-numrene som er av interesse, søke i det store TSV-nummeret om gangen i den første kolonnen. Hvis tallet er inneholdt i den første kolonnen, vil jeg at det skal skrive den linjen til en fil, og deretter søke etter neste ID. Jeg vil ha alle resultatene i en enkelt fil.

Jeg er sikker på at gjennom alle trinnene mine for å komme hit er det en enklere måte å gjøre dette på, men jeg er tydeligvis ikke sikker på hvordan jeg skal lage dette tydeligere. Jeg vil at den skal søke i den store TSV for " 66106 " i kolonne 1, og når den finner linjen for å skrive hele linjen inn en fil. Søk deretter etter " 66107 " og når den finner den, legger den til den samme filen. På denne måten har jeg en enkelt fil, Kan være en CSV eller TSV, med 1200 oppføringer i stedet for flere millioner.

Kommentarer

  • Hvorfor ikke bare analysere TSV direkte? awk -F '\t' skiller inndatafelt etter faner. Og faktisk vil awk skille felt med sammenhengende mellomrom. Så for å få alle blåøyne mennesker (og bevare overskriften), trenger du bare awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Jeg prøvde å kjøre denne kommandoen på en prøvefil kalt " test.tsv ", med samme inngang som oppført ovenfor, men det ga en uvanlig utgang. Det erstattet bare øyefargene med " Blå " mens alt annet var det samme.
  • $3 = "Blue" skal være $3 == "Blue". Førstnevnte er en oppgave, sistnevnte er en sammenligning.
  • Er dette en CSV eller TSV?
  • Å pusse ut informasjonen om dine behov en brødsmule om gangen er ikke ' en god tilnærming til å få en god løsning. Vennligst rediger spørsmålet ditt for å gi et mer virkelig representativt eksempel på hva det er du ' prøver å gjøre. Inkluder en TSV-fil, en CSV-fil og forventede utdatafiler du forventer gitt som input. Sørg for at du dekker alle brukssakene dine, f.eks. om alle treffene er mot verdier i en kolonne eller forskjellige treff i forskjellige kolonner osv. Se Hvordan spørre .

Svar

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

Det høres ut som det du virkelig prøver å gjøre er å lage en ny fil per ID som, forutsatt at IDene er unike som i eksemplet ditt, ville være:

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

eller hvis du vil at hver utdatafil skal inkludere overskriften:

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

Kommentarer

  • Jeg har redigert den for klarhetens skyld, men jeg vil egentlig bare ha en fil som inneholder de På grunn av at dataene var enorme, prøvde jeg bare å lage et eksempel for demonstrasjonsformål, men jeg ' er nytt for programmering, så jeg ' er ikke sikker på om jeg ' uttrykker ordentlig det jeg trenger.

Svar

For alle som kan finne dette i fu tur, jeg har en løsning. Det første jeg gjorde var å konvertere TSV til en CSV ved hjelp av:

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

Så å søke etter filkoden jeg lette etter er:

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

Dette vil søke i den første kolonnen etter teksten i en separat CSV. I dette tilfellet er " file1 " filen du skal søke etter og " file2 " inneholder strengene du vil søke etter. Begge disse filene er i CSV-format.

Dette produserte en egen CSV-fil som inneholdt alle linjene i fil1 som hadde en viss ID i kolonne 1 som samsvarer med en av ID-ene som finnes i fil2.

Jeg håper det hjelper noen en dag, fordi dette har ødelagt hjernen min i flere uker. Jeg fikk ikke engang løsningen selv, sjefen min måtte vise den for meg.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *