CSV-tietojen käyttäminen awk

Yritän löytää tapaa ottaa yksittäiset tiedot CSV-tiedostosta ja käyttää niitä muuttujana grep- tai awk-komento. Kumpikin näyttää sopivalta, mutta en ole varma, kuinka käsken sitä tekemään tämä oikein.

Minulla on esimerkiksi TSV-muodossa oleva tietojoukko, joka näyttää tältä:

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

Tämä ei ole varsinainen tietojoukko, mutta käyttäytyy samalla tavalla. Tämä on koko proteiinia sitova tietokanta, TSV on 300 Mt, miljoonia merkintöjä ja kymmeniä sarakkeita, joten en voi” puhtaasti ” sisältää todellisen.

Haluan tehdä tiedoston, joka sisältää rivit henkilöillä, joilla on siniset silmät, joten olen luonut CSV-tiedoston, joka koostuu " ID " -sarakkeesta, joka tässä tapauksessa näyttäisi tältä:

1, 2, 5

Tämä CSV, joka sisältää " ID " luotiin käyttämällä " Grep " -komento avainsanan etsimiseksi.

Haluan lopulta TSV-tiedoston, joka näyttää tältä: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Mutta en näytä selvittää kuinka tehdä se. Voin luoda sen erikseen kullekin merkinnälle käyttämällä awk tai grep ja sisällyttämällä tunnusnumeron kriteereinä, mutta CSV I: llä on 1200 merkintää, joten haluaisin automatisoida tämän prosessin.

Alla on koodi se tuottaa halutun tuloksen yhdelle merkinnälle, mutta haluan käyttää ID-numeroita automaattiseen hakuun.

BindindDB_All.tsv on lähdetiedostoni, useita miljoonia merkintöjä. Tämä tuottaa TSV: n nimeltä " new.tsv " ja sisältää koko BindindDB_All.tsv-tiedoston rivin, jossa tunnus (sarakkeessa 1) on 66106.

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

Haluaisin tehdä jotain tällaista:

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

missä se lukisi jokainen tunnus, tulosta rivi new.csv-tiedostoon, lue sitten seuraava tunnus ja tee sama.

CSV-tiedosto sisältää 1200 hakutermiä, jota verrataan useisiin miljooniin mahdollisuuksiin, joista jokaisella on yksilöllinen tunnus. tarvitsevat sitä VAIN hakemaan saraketta 1, koska se löytää tunnuksen muista muuttujista kussakin rivissä.

Yhteenvetona totean, että tarvitsen sen etsimään rivin 1 saraketta, vertaamaan sitä CSV-tiedostoni ensimmäiseen numeroon ja tarkistamaan, onko se osuma. Jos se ei ole ottelu, sen on tarkistettava sarakkeen 1 seuraava rivi ja niin edelleen, kunnes se löytää ottelun. Kun se löytää rivin, jossa sarake 1 vastaa CSV: n ensimmäistä datapistettä, haluan sen antavan rivin. Sitten haluan sen toistuvan CSV: n toisen merkinnän kohdalla, kunnes se on löytänyt kaikki 1200 riviä.

Onko sinulla ideoita? Se kuulostaa silmukka-ongelmalta, mutta en myöskään tiedä miten se toimii.

MUOKKAA:

Koska ihmiset näyttävät edelleen olevan valmiita auttamaan, yritän vastata kysymyksiin jotka on lähetetty.

Tässä ovat todelliset tietoni kuusi ensimmäistä merkintää, jotka sisältävät tunnusnumeroita, joita käytetään hakuparametreina.

66106 66107 66108 66109 66110 50127715 

Sarakkeiden nimiä, muita tietoja ei ole. Nämä ovat arvoja, jotka haluan etsiä erikseen toisesta tiedostosta, TSV: stä. Olen myös väärin puhunut TSV-koon suhteen, minulla on 4 Gt: n TSV, joka pakataan 300 Mt. Tiedosto sisältää enemmän merkintöjä kuin mikään ohjelmistani sallii sen edes tarkastella. Alla on esimerkki yksittäisestä merkinnästä useista miljoonista. TARVITaan, että kaikki nämä tiedot on kerralla kerralla, joten sen rajaaminen ei ole vaihtoehto.

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-metyyli-2- (1-propyylibutyyli) – (6aR, 9aS) -3,4,5,8-tetrahydrosyklopenta [4,5] imidatso [2,1-b] puriini-4- yksi :: CHEMBL280307 Fosfodiesteraasi 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, 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 Kalsium / kalmoduliinista riippuvainen 3″ , 5″ -syklinen nukleotidifosf odiesteraasi 1A PDE1A_BOVIN P14100 Q08E30, Q28063

En ole varma, miten tämä luetaan TSV: ksi tässä kentässä, mutta 50127715 on ensimmäinen sarake, ID-sarake. Haluan, että alkuperäinen CSV-tiedostoni, joka sisältää mielenkiinnon kohteena olevat ID-numerot, etsii suurelta TSV: ltä yksi tunnistenumero kerrallaan ensimmäisestä sarakkeesta. Jos numero on ensimmäisessä sarakkeessa, haluan, että se kirjoittaa kyseisen rivin tiedostoon ja etsi sitten seuraava tunnus. Haluan kaikki tulokset yhteen tiedostoon.

Olen varma, että kaikissa vaiheissani tänne pääsemiseksi on helpompi tapa tehdä tämä, mutta en selvästikään ole varma, kuinka tehdä tämä selkeämmin. Haluan, että se etsii suuresta TSV: stä sarakkeesta 1 " 66106 " ja kun se löytää rivin, johon koko rivi kirjoitetaan tiedosto. Etsi sitten hakusanaa " 66107 " ja kun se löytyy, lisää se samaan tiedostoon. Tällä tavalla minulla on yksi tiedosto, joka voi olla CSV tai TSV, ja siinä on 1200 merkintää useiden miljoonien sijasta.

Kommentit

  • Miksi ei vain jäsentää TSV suoraan? awk -F '\t' erottaa syöttökentät välilehdillä. Ja oletusarvoisesti awk erottaa kentät peräkkäisillä välilyönneillä. Joten kaikkien sinisilmäisten ihmisten saamiseksi (ja otsikon säilyttämiseksi) tarvitset vain awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Yritin suorittaa tämän komennon esimerkkitiedostossa nimeltä " test.tsv ", samalla syötteellä kuin yllä, mutta se tuotti kuitenkin epätavallisen ulostulon. Se vain korvasi kaikki silmävärit " sinisellä ", kun taas kaikki muu pysyi samana.
  • $3 = "Blue" tulee olla $3 == "Blue". Ensimmäinen on tehtävä, jälkimmäinen on vertailu.
  • Onko tämä CSV vai TSV?
  • Vaatimuksistasi tietojen jakaminen leivänmuruksi kerrallaan ei ole ' ta hyvä lähestymistapa hyvän ratkaisun saamiseen. muokkaa kysymystäsi antamaan todellisempi esimerkki siitä, mitä sinä yrität tehdä. ' yrität tehdä. Sisällytä TSV-tiedosto, CSV-tiedosto ja odotetut tulostiedostot, jotka odotat, koska ne ovat syötteenä. Varmista, että katat kaikki käyttötapauksesi, esim. vastaavatko kaikki vastaavuudet yhden sarakkeen arvoja vai eri vastaavuuksia eri sarakkeissa jne. Katso Kuinka kysyä .

Vastaus

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

Kuulostaa siltä, että yrität todella tehdä, on kuitenkin luoda uusi tiedosto tunnusta kohden, joka olettaen, että tunnukset ovat ainutlaatuisia, kuten esimerkissäsi, olisi:

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

tai jos haluat, että kukin ulostulotiedosto sisältää otsikon:

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

Kommentit

  • Olen muokannut sitä selkeyden vuoksi, mutta haluan todella vain yhden tiedoston, joka sisältää nämä Koska data on valtava, yritin vain tehdä esimerkkisarjan esittelytarkoituksiin, mutta olen ' uusi ohjelmoinnissa, joten ' en ole varma, ilmaisinko ' ilmaisemalla oikein tarvitsemani.

Vastaa

Kaikille, jotka saattavat löytää tämän fu: sta Minulla on ratkaisu. Ensimmäinen asia, jonka tein, oli muuntaa TSV CSV: ksi käyttämällä:

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

Sitten etsin etsimääni tiedostokoodia:

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

Tämä etsii ensimmäisestä sarakkeesta erilliseen CSV-tiedostoon sisältyvää tekstiä. Tässä tapauksessa " tiedosto1 " on haettava tiedosto ja " tiedosto2 " sisältää etsittävät merkkijonot. Molemmat tiedostot ovat CSV-muotoisia.

Tämä tuotti erillisen CSV-tiedoston, joka sisälsi kaikki tiedoston1 rivit, joiden sarakkeessa 1 oli tietty tunnus, joka vastaa yhtä tiedostossa 2 olevista tunnuksista.

Toivottavasti tämä auttaa joku jonain päivänä, koska tämä on murtanut aivoni viikkojen ajan. En edes saanut ratkaisua itse, pomoni piti näyttää se minulle.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *