n° 186
Luglio/Agosto 2013
Giugno 19, 2013, 07:37:17 pm *
Benvenuto! Accedi o registrati.
Hai dimenticato l'e-mail di attivazione?

Accesso con nome utente, password e durata della sessione
Notizia:
 
   Indice   Linux Windows Techassistance Gameassistance videogame hardware Aiuto Ricerca Agenda Downloads Accedi Registrati  

* Messaggi recenti
Messaggi recenti
Pagine: [1]   Vai giù
  Stampa  
Autore Discussione: Migliorare performance grep su script .sh  (Letto 812 volte)
0 utenti e 1 Utente non registrato stanno visualizzando questa discussione.
francescopi
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 4


Mostra profilo
« inserita:: Giugno 10, 2012, 03:46:55 pm »

Salve a tutti,

ho il seguente problema ho 2 file csv.

Il primo che chiaamo confronto.csv solo una colonna a lunghezza fissa di circa 10000 righe

aaa
bbb
ccc
ddd

il secondo di 5 colonne che chiamo master.csv di 20 mega e circa 300000 righe del tipo

"aaa";"pippo";"pluto";"paperino";"data"
"aaa";"casa";"albero";"finestra";"data"
"fff";"prova";"prova";"prova";"data"

ecc
ecc


io devo pulire il file master.csv delle righe con la prima colonna contenente i valori del file confronto

il comando che ho inserito nello script è del tipo

grep -v -f confronto.csv master.csv > pulito.csv

pulito.csv dovrebbe contenere

"fff";"prova";"prova";"prova";"data"

Siccome ho 30 minuti di tempo per far eseguire la cosa è ho visto che ci mette di più cè un modo per sfruttare il multiprocessore con grep visto che mi sa sfrutta solo un processore?

O cmq un comando che faccia la stessa cosa in tempi molto più veloci o un ottimizzazione di grep?

Grazie mille..


cmq la macchina è una red hat con 16 gb di ram e 8 processori.....
Registrato
M.A.W. 1968
** LEGGETE IL REGOLAMENTO ! **
Global Moderator
Hero Member
*****

Karma: +205/-15
Scollegato Scollegato

Messaggi: 2709


Discrete And Combinatorial Mathematics


Mostra profilo WWW
« Risposta #1 inserita:: Giugno 10, 2012, 07:25:54 pm »

In linea generale, non hai molte chance: puoi ricompilare grep sulla tua architettura attivando le opzioni di threading multiprocessore di GCC (auguri...), oppure scrivere un breve applicativo ad hoc in C, che eseguirà in una ridicola frazione del tempo richiesto al grep standard, usando algoritmi avanzati di pattern matching e altri accorgimenti (non banali, se non hai familiarità con la problematica e con l'ottimizzazione in generale).
Registrato

I Moderatori invitano tutti gli utenti a prendere visione del REGOLAMENTO e a rispettarlo.

Un blog? Io? Occhiolino
francescopi
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 4


Mostra profilo
« Risposta #2 inserita:: Giugno 10, 2012, 09:21:21 pm »

ti ringrazio della risposta non sono pratico delle cose che dici tu purtroppo...

non se se usando fgrep o comm la cosa migliora leggevos ono più performanti...

altrimenti non si potrebbe splittare il file maste in piu gile e far partire in modo parallelo e non seriale n grep che ognuna sfrutta un processore?
Registrato
ctraversa
Jr. Member
**

Karma: +14/-7
Scollegato Scollegato

Messaggi: 155


Mostra profilo
« Risposta #3 inserita:: Giugno 10, 2012, 10:38:19 pm »

Ciao francescopi.
Domanda. Devi usare grep obbligatoreamente? Oppure puoi scegliere altre strade a patto di arrivare in tempi brevi alla soluzione del tuo problema (sempre meno di 30 minuti)? Dato che non lo hai specificato poichè hai scritto solo
Citazione
io devo pulire il file master.csv delle righe con la prima colonna contenente i valori del file confronto
suppongo tu possa utilizzare altre vie. Personalmente quindi risolverei la cosa con uno script in cui carico i contenuti dei due files su di un DB. Utilizzando postgresql nello script ci metterei i comandi:
Codice:
copy confronto from 'path_to_your_files/confronto.csv';
copy master from 'path_to_your_files/master.csv';
E' chiaro che devi aver predistosto opportunamente le tabelle ed i campi relativi sul DB. A questo punto eseguirei la query sul DB (ovviamente nello script devvi aggiungere la parte di comandi per eseguire la query)
Codice:
delete from master where nome_prima_clonna IN (select nome_prima_clonna from confronto)
infine
Codice:
copy (select * from master) to 'path_to_your_files/pulito.csv';
In pratica in questo modo non ho fatto altro che utilizzare un DB al posto di grep o di scrivere in C algoritmi di pattern matching come suggeriva MAW o binary search ecc. per ottimizzare la pulitura del file master.csv dal momento che i DB nascono proprio per fare questo
Se lo fai in postgresql non dovresti impiegare più di 30 secondi per eliminare dai 300.000 record di master.csv i 10.000 record in confronto.csv.
Chiaramente devi creare opportunamente i campi chiave sulle tabelle del DB. L'uso delle 8 CPU è garantito dal SO linux che sceglie su quale CPU sia + opportuno eseguire il singolo processo. A tal proposito puoi darti una lettura qui:
http://archives.postgresql.org/pgsql-admin/2004-03/msg00116.php
ed ai suoi Follow-Ups
L'unico problema che invece vedrei in un tale approccio, potrebbe essere quello di caricare i files sulle tabelle del DB. Anche dividendo il file master.csv in un multiplo di 8 parti in modo da lanciare gli 8 caricamenti in paralleo in quel caso il collo di bottiglia potrebbe essere rappresentato dall'HD. Potresti migliorarlo con un RAID 1 ma sarebbero comunque tutti test da fare perchè non sapendo l'HW che hai a disposizione è difficile immaginare il tempo necessario per caricare 1 file di 20 mega sulla tabella.


Registrato
francescopi
Newbie
*

Karma: +0/-0
Scollegato Scollegato

Messaggi: 4


Mostra profilo
« Risposta #4 inserita:: Giugno 11, 2012, 12:45:28 am »

ti ringrazio della risposta....

si avevo pendato anche io a una soluzione tramite db..
ma considera che lo script elabora 5 diversi flussi csv e questo è il caso pipu corpopso mentre gli altri sono molto veloci e immediati....

Poi considera che mi sono messo nel caso limite per stare tranquillo quindi in teoria il file master non dovrebbe essere di 20 mega ma forse di 10 o 5 mega e il file di confronto di circa 1000 righe...

Siccome in passato qualche csv era di 20 mega ho preso il caso questa casistica per avere un margine sicuri ma non è detto accada più perchè i dati dovrebbero diminuire che sono csv che venogno da un'altro db e da 20 mega ultimamente si sono attestati a 5 mega....

allora ecco perchè in un unico script volevo utilizzare grep un po per tutto...se no dovrei cmq crearmi un sqloader( il db è oracle) caricare i csv elaborare la differnza e creare un nuovo csv...

Per quello mi sembrava piu semplice con un grep la cosa più immediati e facile.....
Però non è detto che non escludo l'ippotesi db ma i 20 mega con 200-300 mila record non è detto accada più....

Se no provare la paralellilazione delle grep se non voglio usare l'ipotesi db...il C o un programma in C lo escludo che non saprei proprio dove andare a sbattere
Registrato
zeroConsole
Jr. Member
**

Karma: +1/-26
Scollegato Scollegato

Messaggi: 198


01000011 01101001 01100001 01101111

lex13@live.it
Mostra profilo
« Risposta #5 inserita:: Giugno 12, 2012, 01:37:04 pm »

Credo che in questo caso(oltre l'ottimo suggerimento del db), tu debba affrontare in modo ponderato l'uso del potentissimo "SED", è un comando veramente potente e veloce, ha solo un problemino....non è facile capire come usarlo, io l'ho usato poco, ma forse potrebbe fare al caso tuo...
E' una di quelle cose che so che c'è, ma che non ho mai affrontato..
Registrato

<0>Kernel - panic not syncing: Fatal Exception
ctraversa
Jr. Member
**

Karma: +14/-7
Scollegato Scollegato

Messaggi: 155


Mostra profilo
« Risposta #6 inserita:: Giugno 12, 2012, 02:19:20 pm »

Ciao Lex13.
Conoscevo il comando sed anzi nel caso possa essere utile ad altri, all'occorrenza io faccio sempre riferimento a questo link
http://www.grymoire.com/Unix/Sed.html#uh-0
Tuttavia non l'ho proposto poichè esso agisce sulla base di uno o più comandi (il comando -e permette di mettere più comandi assieme) ognuno contenente una parola od una regular expression.
Nel caso di francescopi si deve eliminare un insieme di righe sulla base di un insieme di parole contenute in un altro file. Questo richiederebbe la preventiva generazione di uno script da dare in seguito in pasto a SED in cui viene creata la sequenza di comandi di cancellazione delle righe contenenti ciascuna una parola dell'elenco.
E' per questo motivo che avevo scartato il comando SED. Perchè a mio avviso la fase di generazione del file dei comandi è più complicata.
Comunque sarà francescopi a decidere.
Registrato
Pagine: [1]   Vai su
  Stampa  
 
Vai a:  

Copyright © 2011 Edizioni Master SpA. p.iva : 02105820787

Tutti i diritti di proprietà letteraria e artistica riservati. - Privacy



Links to Page