Brug af CSV-data med awk

Jeg forsøger at finde en måde at tage de individuelle data fra en CSV-fil og bruge dem som en variabel i en grep eller awk kommando. Enten synes passende, men jeg er ikke sikker på, hvordan jeg skal fortælle det, at det skal gøres korrekt.

For eksempel har jeg et datasæt i TSV-format, der ser sådan ud:

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 det egentlige datasæt, men opfører sig på samme måde. Dette er hele proteinbindingsdatabasen, TSV er 300 MB med millioner af poster og snesevis af kolonner, så jeg kan ikke rent inkluderer den rigtige ting.

Jeg vil oprette en fil, der indeholder rækkerne med personer, der har blåt øje, så jeg har oprettet en CSV-fil, der består af " ID " kolonne, som i dette tilfælde ville se sådan ud:

1, 2, 5

Denne CSV indeholdende " ID " blev genereret ved hjælp af " Grep " kommando for at søge efter nøgleudtrykket.

Jeg vil i sidste ende have en TSV-fil, der ser sådan ud: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Men jeg kan ikke synes at finde ud af hvordan gør man det. Jeg kan oprette det individuelt for hver post ved hjælp af awk eller grep og inkludere ID-nummeret som et kriterium, men den CSV, jeg bruger, har 1200 poster, så jeg vil gerne automatisere denne proces.

Nedenfor er kode der vil producere det ønskede resultat for en enkelt post, men jeg vil bruge ID-numrene til at søge automatisk.

BindindDB_All.tsv er min kildefil med flere millioner poster. Dette vil producere en TSV kaldet " new.tsv " og indeholder hele rækken i BindindDB_All.tsv-filen, hvor IDet (i kolonne 1) er lig med 66106.

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

Jeg vil gerne gøre noget som dette:

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

hvor det læser hvert id, udskriv linjen til new.csv, læs derefter det næste id og gør det samme.

CSV-filen indeholder 1200 søgeudtryk, der skal sammenlignes med flere millioner muligheder, hver med et unikt id. I har brug for det til KUN at søge i kolonne 1, da det finder IDet inden for andre variabler es i hver række.

For at opsummere har jeg brug for det for at se i kolonne 1 i rækken, sammenligne det med det første nummer i min CSV-fil og se, om det er et match. Hvis det ikke er et match, skal det kontrollere næste række i kolonne 1 og så videre, indtil det finder matchet. Når den finder rækken, hvor kolonne 1 matcher CSVs første datapunkt, vil jeg have den til at udføre rækken. Så vil jeg have det til at gentage for den anden post i CSV, indtil den har fundet alle 1200 rækker.

Har du nogen ideer? Det lyder som et loopproblem, men jeg ved heller ikke, hvordan jeg får det til at fungere.

REDIGER:

Da folk stadig synes at være villige til at hjælpe, så lad mig prøve at besvare spørgsmålene der er blevet sendt.

Her er de første 6 poster af mine rigtige data, der indeholder ID-numre, der vil blive brugt som søgeparametre.

66106 66107 66108 66109 66110 50127715 

Der er ingen kolonnenavne, ingen andre data. Dette er værdier, som jeg vil søge efter individuelt i en anden fil, en TSV. Jeg har også forkert forkert med hensyn til TSV-størrelsen, jeg har en 4 GB TSV, der komprimeres til 300 MB. Filen indeholder flere poster, end nogen af mine programmer tillader den at se jævn. Nedenfor er et eksempel på en enkelt post ud af flere millioner. Jeg har brug for, at alle disse data trækkes på én gang, så beskæring er ikke en mulighed.

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-methyl-2- (1-propylbutyl) – (6aR, 9aS) -3,4,5,8-tetrahydrocyclopenta [4,5] imidazo [2,1-b] purin-4- en :: CHEMBL280307 Phosphodiesterase 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 44.272.162 103.967.010 CHEMBL280307 ZINC28221715 1 MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS Calcium / calmodulin-afhængig 3″ , 5″ -cyklisk nukleotidphosph odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Jeg er ikke sikker på, hvordan jeg får denne til at læse som en TSV inden for denne boks, men 50127715 er den første kolonne, ID-kolonnen. Jeg ønsker at have min oprindelige CSV-fil, der indeholder de relevante ID-numre, søge i det store TSV-nummer et ad gangen inden for den første kolonne. Hvis nummeret er indeholdt i den første kolonne, vil jeg have det til at skrive linjen til en fil og derefter søge efter det næste ID. Jeg vil have alle resultaterne i en enkelt fil.

Jeg er sikker på, at i alle mine trin for at komme her er der en lettere måde at gøre dette på, men jeg er helt klart ikke sikker på, hvordan jeg laver dette tydeligere. Jeg vil have det til at søge i den store TSV efter " 66106 " i kolonne 1, og når den finder linjen til at skrive hele linjen ind en fil. Søg derefter efter " 66107 ", og når den finder den, føjes den til den samme fil. På denne måde har jeg en enkelt fil, kan være en CSV eller TSV, med 1200 poster i stedet for flere millioner.

Kommentarer

  • Hvorfor ikke bare parse TSV direkte? awk -F '\t' adskiller inputfelter efter faner. Og faktisk awk adskiller felter efter sammenhængende mellemrum. Så for at få alle blåøjne mennesker (og bevare overskriften) behøver du bare awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Jeg prøvede at køre denne kommando på en prøvefil kaldet " test.tsv " med den samme input som angivet ovenfor, men den producerede en usædvanlig output. Det erstattede bare alle øjenfarverne med " Blå " mens alt andet var det samme.
  • $3 = "Blue" skal være $3 == "Blue". Førstnævnte er en opgave, sidstnævnte er en sammenligning.
  • Er dette en CSV eller TSV?
  • Udskæring af oplysningerne om dine behov er en brødkrumme ad gangen ikke ' en god tilgang til at få en god løsning. rediger dit spørgsmål for at give et mere virkeligt repræsentativt eksempel på, hvad det er, du ' forsøger at gøre. Inkluder en TSV-fil, en CSV-fil og de forventede outputfiler, du forventer, givet det som input. Sørg for at dække alle dine brugssager, f.eks. om alle matches er mod værdier i 1 kolonne eller forskellige matches i forskellige kolonner osv. Se Sådan spørger du .

Svar

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

Det lyder som, hvad du virkelig prøver at gøre, er dog at oprette en ny fil pr. id, som forudsat, at iderne er unikke som i dit eksempel, ville være:

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

, eller hvis du vil have, at hver outputfil skal indeholde 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 redigeret det for at gøre det klart, men jeg vil virkelig kun have 1 fil, der indeholder dem navne. På grund af dataens natur er enorme, prøvede jeg bare at lave et eksempel til demonstrationsformål, men jeg ' er ny til programmering, så jeg ' er ikke sikker på, om jeg ' udtrykker ordentligt, hvad jeg har brug for.

Svar

For alle, der måske finder dette i fu tur, jeg har en løsning. Den første ting, jeg gjorde, var at konvertere TSV til en CSV ved hjælp af:

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

Derefter skal jeg søge efter min filkode:

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

Dette søger i den første kolonne efter teksten i en separat CSV. I dette tilfælde er " fil1 " den fil, der skal søges i, og " fil2 " indeholder de strenge, der skal søges efter. Begge disse filer er i CSV-format.

Dette producerede en separat CSV-fil, der indeholdt alle linjerne i fil1, som havde et bestemt ID i kolonne 1, der matcher et af de IDer, der er indeholdt i fil2.

Jeg håber, det hjælper nogen en dag, fordi dette har ødelagt min hjerne i flere uger. Jeg fik ikke engang løsningen selv, min chef måtte vise mig den.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *