|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
Migliorare performance grep su script .sh
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.. Non so se sia la corretta sezione o andava in programmazione. cmq la macchina è una red hat con 16 gb di ram e 8 processori..... Ultima modifica di francescopi : 10-06-2012 alle 14:41. |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) Ultima modifica di Gimli[2BV!2B] : 11-06-2012 alle 21:16. Motivo: Tolto sleep inutile |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
ti ringrazio per la risposta....la devo un'attimo elaborare che ho iniziato da poco a usare script unix e linux..
cmq anche io ho letto che fgrep e comm sono più performanti..magari prima provo a vedere se fgrep -vFf è più performante e poi provo a studiarmi la tua soluzione.... io per paralelizzare volevo splittare il file master in 4 file con spli t poi usare 4 grep -vf in parallelo per sfruttare ognuna un processore... é possibile come cosa?il problema che i file splittati sono diversi ma il file di confronto è lo stesso.....cè un comando che possa paralelizzare le grep senz farli sequenziali del tippo : grep -vf confronto.csv file1 >pulito1.csv grep -vf confronto.csv file2 >pulito2.csv grep -vf confronto.csv file3 >pulito3.csv grep -vf confronto.csv file4 >pulito4sv e pio unire i 4 file puliti in un unico file?ma senza fargli fare le grep una dopo l' altra ma tutte in parallelo? Ultima modifica di francescopi : 10-06-2012 alle 20:12. |
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Lo script esegue esattamente N grep contemporaneamente (N è il terzo argomento).
Suddivide il fine di input in N parti, in RAM, quindi lancia N grep, salvando l'output in file temporanei. Aspetta quindi che tutti i grep terminino, e da come output il contenuto degli N file temporanei rispettando l'ordine iniziale. In uscita elimina i file temporanei.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
Quote:
pensavo fosse piu semplicefare una split invece hai fatto uno script bello lungoi con tutte quelle variabili complimenti ![]() cmq sgrep su red hat non cè e nemmeno fgrep cè solo grep -f che ci si avvicina mi sa.... ma multi.sh è il nome dello script che divide i file e laancia i grep in parallelo? quindi nel mio script devo richiamarlo? |
|
![]() |
![]() |
![]() |
#6 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Sì, io l'ho chiamato multi.sh, tu puoi dargli il nome che desideri.
L'alternativa più manuale, dividendo il file master.csv in più parti, è simile a quanto hai scritto: Codice:
grep -vf confronto.csv file1 >pulito1.csv & grep -vf confronto.csv file2 >pulito2.csv & grep -vf confronto.csv file3 >pulito3.csv & grep -vf confronto.csv file4 >pulito4.csv & Non dovrai nemmeno chiudere il terminale in cui hai lanciato l'esecuzione per non bloccare l'elaborazione, anche se non avrai riscontro visivo della sua esecuzione.
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
Quote:
ti ringrazio della cosa.....ma fg cosa fa? un mio amico che lavora ed è espeto di linux mi consigliava di fare un cilco infinito con while finchè tutte le grep non fossero finite e poi interromperlo con break....con fg è piu facile? siccome le grep le dovrebbe eseguire uno scritp non è meglio nohup grep1 & nohup gep2 & ecc ecc ? Grazie sei gentilissimo e mi sa sei un guru di linux ![]() Tu come controlleresti che le grep poi sono finite e assemblare i file puliti in un unico file? |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Nello script ho usato un ciclo simile a quello che descrivi, in questo caso usando fg come "sentinella":
Codice:
# Attendi il termine di tutti i processi figli while [ 1 ]; do fg >/dev/null 2>&1; [ $? == 1 ] && break; done Versione semplificata: Codice:
grep -vf confronto.csv master1.csv > pulito1.csv & grep -vf confronto.csv master2.csv > pulito2.csv & grep -vf confronto.csv master3.csv > pulito3.csv & grep -vf confronto.csv master4.csv > pulito4.csv & #ciclo di attesa termine grep while [ 1 ]; do fg >/dev/null 2>&1 [ $? == 1 ] && break done #unione output #il primo crea il file cat pulito1.csv > pulito.csv #i seguenti aggiungono cat pulito2.csv >> pulito.csv cat pulito3.csv >> pulito.csv cat pulito4.csv >> pulito.csv #pulizie di primavera rm pulito1.csv rm pulito2.csv rm pulito3.csv rm pulito4.csv
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
Quote:
grazie sei gentilissimo era un po l'idea che volevo fare.. volevo poerti altre questioni 1)considera che oggi ho fatto una prova con il file master da 20 mega e circa 200K record e il file di confronto di circa 3000 record una grep ha messo 1 ora ( troppo per me) Quindi direi di parallelizzare in 3-4 grep anche se ho visto che la cpu dal 12% passa al 40% di lavoro e penso non crei problemi no? Il mio amico mi indicava di usare sleep tu dici di no? se puta cosa una grep si impalla o il ciclo va infinito satura la cpu e blocca la macchina invece con uno sleep 1 magari ogni 1 minuto tenta la cosa e non manda la cpu al 100%... Tu che dici? 2) while [ 1 ]; do fg >/dev/null 2>&1 [ $? == 1 ] && break done questo dice finche è true il whiel metti i processi in background sul path buco nero /dev/null 2 giusto? ma >&1 invece cosa fa? poi se l 'ultimo comando è ok interrompe il ciclo giusto? e si inizia a unire i file... Grzie delle risposte esaurienti e pronte..devi avere proprio tanta passione su queste cose ![]() |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Feb 2006
Città: Parma
Messaggi: 3010
|
Classico ciclo infinito
Codice:
while [ 1 ]; do
Codice:
fg >/dev/null 2>&1
Codice:
[ $? == 1 ] && break done Una scrittura funzionalmente equivalente che esegue meno comandi, risultando quindi più elegante secondo i miei standard, è questa: Codice:
while fg; do :; done >/dev/null 2>&1
__________________
~Breve riferimento ai comandi GNU/Linux (ormai non molto breve...) |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Mar 2007
Messaggi: 471
|
Quote:
cmq farò un po di prove quindi dici sleep non serve.... ma l'ultimo comando è proprio cosi : fg; do :; done >/dev/null 2>&1 cioè in mezzo ha solo :; ? Non fa nulla? Ultima cosa per dividere iol file in 4 volevo usare uno split variabile=wc -l master.csv ( colo che l output èdel tipo 200000 master.csv) variabile1=variabile:4 split -l variabile1 master.csv (crea 4 file xaa,xab.xac,xad) Che dici si può fare?il codice non è proprio cosi ma va ottimizzato... |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:46.