Utilizarea datelor CSV cu awk

Încerc să găsesc o modalitate de a lua datele individuale dintr-un fișier CSV și de a le folosi ca variabilă într-un grep sau comandă awk. Oricare pare adecvat, dar „nu sunt sigur cum să-i spun să facă acest lucru în mod corespunzător.

De exemplu, am un set de date în format TSV care arată astfel:

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

Acesta nu este setul de date propriu-zis, ci se comportă în același mod. Aceasta este întreaga bază de date de legare a proteinelor, TSV are 300 MB cu milioane de intrări și zeci de coloane, așa că nu pot să fiu curat includeți adevăratul lucru.

Vreau să creez un fișier care să conțină rândurile cu persoane cu ochi albaștri, așa că am creat un fișier CSV care este format din " ID ", care în acest caz ar arăta astfel:

1, 2, 5

Acest CSV conține " ID " a fost generat utilizând " Grep " comanda pentru a căuta termenul cheie.

În cele din urmă vreau un fișier TSV care să arate astfel: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Dar nu pot părea a-si da seama cum să o facă. Îl pot crea individual pentru fiecare intrare folosind awk sau grep și incluzând numărul de identificare ca criteriu, totuși CSV pe care îl folosesc are 1200 de intrări, așa că aș dori să automatizez acest proces.

Mai jos este codul care va produce rezultatul dorit pentru o singură intrare, dar vreau să folosesc numerele de ID pentru a căuta automat.

BindindDB_All.tsv este fișierul meu sursă, cu câteva milioane de intrări. Aceasta va produce un TSV numit " new.tsv " și conține întregul rând al fișierului BindindDB_All.tsv unde ID-ul (în coloana 1) este egal cu 66106.

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

Aș dori să fac așa ceva:

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

unde s-ar citi fiecare ID, imprimați linia pe new.csv, apoi citiți următorul ID și faceți același lucru.

Fișierul CSV conține 1200 de termeni de căutare, pentru a fi comparați cu câteva milioane de posibilități fiecare cu un ID unic. I trebuie să caute DOAR coloana 1, deoarece va găsi ID-ul în alte variabile este în fiecare rând.

Pentru a rezuma, trebuie să se uite în coloana 1 a rândului, să îl compare cu primul număr din fișierul meu CSV și să văd dacă este o potrivire. Dacă nu este o potrivire, atunci trebuie să verifice următorul rând din coloana 1 și așa mai departe până când găsește potrivirea. Când găsește rândul în care coloana 1 se potrivește cu primul punct de date CSV, vreau să scoată rândul. Apoi vreau să se repete pentru a doua intrare în CSV, până când va găsi toate cele 1200 de rânduri.

Aveți idei? Pare a fi o problemă de buclă, dar nici nu știu cum să fac asta să funcționeze.

EDIT:

Întrucât oamenii par încă dispuși să ajute, permiteți-mi să încerc să răspund la întrebări care au fost postate.

Iată primele 6 intrări din datele mele reale, care conțin numere de ID care vor fi utilizate ca parametri de căutare.

66106 66107 66108 66109 66110 50127715 

Nu există nume de coloane, nu există alte date. Acestea sunt valori pe care vreau să le caut individual într-un fișier diferit, un TSV. Am greșit și în ceea ce privește dimensiunea TSV, am un TSV de 4 GB, care se comprimă 300 MB. Fișierul conține mai multe intrări decât oricare dintre programele mele îi permit să vizualizeze chiar mai jos. Mai jos este un exemplu de intrare unică din câteva milioane. AM NEVOIE ca toate aceste date să fie extrase simultan, deci tăierea nu este opțiune.

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- one :: 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 44272162 103967010 CHEMBL280307 ZINC28221715 1 MGSTATETEELENTTFKYLIGEQTEKMWQRLKGILRCLVKQLEKGDVNVIDLKKNIEYAASVLEAVYIDETRRLLDTDDELSDIQSDSVPSEVRDWLASTFTRKMGMMKKKSEEKPRFRSIVHVVQAGIFVERMYRKSYHMVGLAYPEAVIVTLKDVDKWSFDVFALNEASGEHSLKFMIYELFTRYDLINRFKIPVSCLIAFAEALEVGYSKYKNPYHNLIHAADVTQTVHYIMLHTGIMHWLTELEILAMVFAAAIHDYEHTGTTNNFHIQTRSDVAILYNDRSVLENHHVSAAYRLMQEEEMNVLINLSKDDWRDLRNLVIEMVLSTDMSGHFQQIKNIRNSLQQPEGLDKAKTMSLILHAADISHPAKSWKLHHRWTMALMEEFFLQGDKEAELGLPFSPLCDRKSTMVAQSQIGFIDFIVEPTFSLLTDSTEKIIIPLIEEDSKTKTPSYGASRRSNMKGTTNDGTYSPDYSLASVDLKSFKNSLVDIIQQNKERWKELAAQGEPDPHKNSDLVNAEEKHAETHS calciu / calmodulin-dependentă-3″ , 5″ -fos nucleotidic ciclic odiesterază 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Nu sunt sigur cum să fac acest lucru să fie citit ca un TSV în această casetă, dar 50127715 este prima coloană, coloana ID. Vreau ca fișierul meu CSV inițial, care să conțină numerele de identificare de interes, să caute în TSV mare un număr de identificare la un moment dat în prima coloană. Dacă numărul este cuprins în prima coloană, vreau să scrie linia respectivă într-un fișier, apoi căutați următorul ID. Vreau toate rezultatele într-un singur fișier.

Sunt sigur că de-a lungul tuturor pașilor mei pentru a ajunge aici există o modalitate mai ușoară de a face acest lucru, dar clar nu sunt sigur cum să fac cu atât mai clar. Vreau să caute în TSV mare " 66106 " în coloana 1 și când găsește linia în care scrie întreaga linie în un fișier. Apoi căutați " 66107 " și după ce îl găsește, îl adaugă în același fișier. În acest fel am un singur fișier, poate fi un CSV sau TSV, cu 1200 de intrări, mai degrabă decât câteva milioane.

Comentarii

  • De ce să nu analizăm doar TSV direct? awk -F '\t' va separa câmpurile de intrare prin file. Și într-adevăr, în mod implicit, awk va separa câmpurile prin spațiu alb conigu. Deci, pentru a obține toți oamenii cu ochi albaștri (și pentru a păstra antetul), aveți nevoie doar de awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Am încercat să rulez această comandă pe un fișier exemplar numit " test.tsv ", cu aceeași intrare ca cea enumerată mai sus, totuși a produs o ieșire neobișnuită. Tocmai a înlocuit toate culorile ochilor cu " Albastru " în timp ce toate celelalte au rămas la fel.
  • $3 = "Blue" ar trebui să fie $3 == "Blue". Primul este o misiune, cel de-al doilea este o comparație.
  • Este acesta un CSV sau TSV?
  • Îndepărtarea informațiilor despre cerințele dvs. un fir de pană la un moment dat nu este o abordare bună pentru a obține o soluție bună. Vă rugăm să modificați întrebarea dvs. pentru a oferi un exemplu mai reprezentativ despre ceea ce încercați să faceți '. Includeți un fișier TSV, un fișier CSV și fișierele de ieșire așteptate pe care le așteptați, având în vedere acest lucru ca intrare. Asigurați-vă că acoperiți toate cazurile de utilizare, de ex. dacă toate potrivirile sunt contra valorilor dintr-o coloană sau potriviri diferite în diferite coloane etc. A se vedea Cum să întrebați .

Răspuns

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

Totuși, sună ca ceea ce încerci să faci, este să creezi un nou fișier per ID care, presupunând că ID-urile sunt unice ca în exemplul dvs., ar fi:

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

sau dacă doriți ca fiecare fișier de ieșire să includă antetul:

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

Comentarii

  • Am editat-o pentru claritate, dar chiar vreau doar 1 fișier care conține acelea Datorită naturii datelor fiind enorme, am încercat doar să fac un exemplu setat în scopuri demonstrative, dar ' sunt nou în programare, așa că ' Nu sunt sigur dacă ' exprim corect ceea ce am nevoie.

Răspuns

Pentru oricine poate găsi acest lucru în fu Ture, am o soluție. Primul lucru pe care l-am făcut a fost să convertesc TSV într-un CSV folosind:

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

Apoi, pentru a căuta codul fișierului pe care îl căutam, este:

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

Aceasta va căuta în prima coloană textul conținut într-un CSV separat. În acest caz, " file1 " este fișierul de căutat și " file2 " conține șirurile de căutare. Ambele fișiere au format CSV.

Acest lucru a produs un fișier CSV separat care conținea toate liniile din fișierul 1 care avea un anumit ID în coloana 1 care se potrivește cu unul dintre ID-urile conținute în fișierul2.

Sper că vă va ajuta cândva, pentru că asta mi-a stricat creierul de săptămâni. Nici măcar nu am obținut soluția, chiar șeful meu a trebuit să mi-o arate.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *