Utilizzo dei dati CSV con awk

Sto cercando di trovare un modo per prendere i singoli dati da un file CSV e utilizzarli come una variabile allinterno di un grep o comando awk. Sembra appropriato, ma non sono sicuro di come dirgli di farlo in modo appropriato.

Ad esempio, ho un set di dati in formato TSV che assomiglia a questo:

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

Questo non è il set di dati effettivo, ma si comporta allo stesso modo. Questo è lintero database di legame proteico, il TSV è 300 MB con milioni di voci e dozzine di colonne, quindi non posso” t pulito includere la cosa reale.

Voglio creare un file contenente le righe con individui che hanno gli occhi blu, quindi ho creato un file CSV che è composto da " ID ", che in questo caso sarebbe simile a questa:

1, 2, 5

Questo CSV contenente il " ID " è stato generato utilizzando " Grep " comando per cercare il termine chiave.

Alla fine voglio un file TSV che assomigli a questo: 1 Bill Blue 2 Sam Blue 5 Ted Blue

Ma non posso sembrare per capire come farlo. Posso crearlo individualmente per ogni voce utilizzando awk o grep e includendo il numero ID come criterio, tuttavia il CSV che sto utilizzando ha 1200 voci, quindi vorrei automatizzare questo processo.

Di seguito è riportato il codice che produrrà il risultato desiderato per una singola voce, ma desidero utilizzare i numeri ID per cercare automaticamente.

BindindDB_All.tsv è il mio file sorgente, con diversi milioni di voci. Questo produrrà un TSV chiamato " new.tsv " e contiene lintera riga del file BindindDB_All.tsv dove lID (nella colonna 1) è 66106.

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

Vorrei fare qualcosa di simile:

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

dove leggerebbe ogni ID, stampa la riga su new.csv, quindi leggi lID successivo e fai lo stesso.

Il file CSV contiene 1200 termini di ricerca, da confrontare con diversi milioni di possibilità ciascuno con un ID univoco. I ne ha bisogno per cercare SOLO la colonna 1, poiché troverà lID allinterno di altre variabili es in ogni riga.

Per riassumere, ho bisogno che guardi nella colonna 1 della riga, confrontalo con il primo numero nel mio file CSV e vedi se è una corrispondenza. Se non è una corrispondenza, è necessario controllare la riga successiva nella colonna 1 e così via finché non trova la corrispondenza. Quando trova la riga in cui la colonna 1 corrisponde al primo punto dati CSV, voglio che emetta la riga. Quindi voglio che si ripeta per la seconda voce nel CSV, finché non ha trovato tutte le 1200 righe.

Qualche idea? Sembra un problema di loop, ma non so nemmeno come farlo funzionare.

MODIFICA:

Poiché le persone sembrano ancora disposte ad aiutare, lasciami provare a rispondere alle domande che sono stati pubblicati.

Ecco le prime 6 voci dei miei dati reali, contenenti numeri ID che verranno utilizzati come parametri di ricerca.

66106 66107 66108 66109 66110 50127715 

Non ci sono nomi di colonne, nessun altro dato. Questi sono valori che voglio cercare individualmente in un file diverso, un TSV. Ho anche sbagliato a parlare della dimensione del TSV, ho un TSV da 4 GB, che si comprime in 300 MB. Il file contiene più voci di quante i miei programmi gli consentano di visualizzare. Di seguito è riportato un esempio di una singola voce su diversi milioni. HO BISOGNO che tutti questi dati vengano estratti contemporaneamente, quindi tagliarli non è un opzione.

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 / h 11-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-tetraidrociclopenta [4,5] imidazo [2,1-b] purin-4- uno :: CHEMBL280307 Fosfodiesterasi 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 calcio / calmodulina-dipendenti 3″ , 5″ -fosfo nucleotidico ciclico odiesterase 1A PDE1A_BOVIN P14100 Q08E30, Q28063

Non sono sicuro di come leggerlo come TSV allinterno di questa casella, ma 50127715 è la prima colonna, la colonna ID. Voglio avere il mio file CSV iniziale, contenente i numeri ID di interesse, cercare il grande numero di ID TSV uno alla volta allinterno della prima colonna. Se il numero è contenuto nella prima colonna, voglio che scriva quella riga in un file, quindi cerco lID successivo. Voglio tutti i risultati in un unico file.

Sono sicuro che durante tutti i miei passaggi per arrivare fin qui cè un modo più semplice per farlo, ma chiaramente non sono sicuro di come farlo questo più chiaro. Voglio che cerchi nel TSV grande " 66106 " nella colonna 1 e quando trova la riga in cui scrivere lintera riga un file. Quindi cerca " 66107 " e, una volta trovato, lo aggiunge allo stesso file. In questo modo ho un singolo file, può essere CSV o TSV, con 1200 voci anziché diversi milioni.

Commenti

  • Perché non analizzare direttamente il TSV? awk -F '\t' separerà i campi di input in tabulazioni. E infatti per impostazione predefinita awk separerà i campi con spazi vuoti conigui. Quindi, per ottenere tutte le persone con gli occhi azzurri (e preservare lintestazione), è sufficiente awk -F '\t' 'BEGIN { OFS="\t" } NR==1 { print } NR>1 && $3 = "Blue" { print }'.
  • Ho provato a eseguire questo comando su un file di esempio chiamato " test.tsv ", con lo stesso input elencato sopra, tuttavia ha prodotto un output insolito. Ha appena sostituito tutti i colori degli occhi con " blu " mentre tutto il resto è rimasto lo stesso.
  • $3 = "Blue" dovrebbe essere $3 == "Blue". Il primo è un compito, il secondo è un confronto.
  • È un CSV o TSV?
  • Distribuire le informazioni sui requisiti un breadcrumb alla volta non è ' è un buon approccio per ottenere una buona soluzione. modifica la tua domanda per fornire un esempio più rappresentativo di ciò che ' stai cercando di fare. Includi un file TSV, un file CSV e i file di output previsti che ti aspetti dato che come input. Assicurati di coprire tutti i tuoi casi duso, ad es. se tutte le corrispondenze sono rispetto a valori in 1 colonna o corrispondenze diverse in colonne diverse, ecc. Vedi How to Ask .

Risposta

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

Sembra che quello che stai veramente cercando di fare, però, è creare un nuovo file per ID che, supponendo che gli ID siano univoci come nel tuo esempio, sarebbe:

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

o se desideri che ogni file di output includa lintestazione:

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

Commenti

  • Lho modificato per chiarezza, ma in realtà voglio solo 1 file contenente quelli nomi. A causa della natura dei dati che sono enormi, ho appena provato a creare un set di esempio a scopo dimostrativo, ma ' sono nuovo nella programmazione, quindi ' Non sono sicuro di ' esprimo correttamente ciò di cui ho bisogno.

Rispondi

Per chiunque possa trovarlo nel fu turo, ho una soluzione. La prima cosa che ho fatto è stata convertire il TSV in un CSV utilizzando:

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

Quindi per cercare il codice del file che stavo cercando è:

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

Questo cercherà nella prima colonna il testo contenuto in un CSV separato. In questo caso, " file1 " è il file da cercare e " file2 " contiene le stringhe da cercare. Entrambi i file sono in formato CSV.

Questo ha prodotto un file CSV separato che conteneva tutte le righe allinterno di file1 che avevano un certo ID nella colonna 1 che corrisponde a uno degli ID contenuti in file2.

Spero che aiuti qualcuno un giorno, perché questo mi ha distrutto il cervello per settimane. Non ho nemmeno trovato la soluzione da solo, il mio capo ha dovuto mostrarmela.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *