lunedì 21 marzo 2011

"Un breve grep grep di ranelle"

Il titolo di questo post è un omaggio alla poesia "La mia sera"di Giovanni Pascoli. E' vero, lì le ranelle facevano "gre gre", qui fanno grep grep. Comunque sia, sempre di omaggio si tratta. :D

Avete mai provato a leggere la pagina man del comando grep? 455 linee di morbidezza. Ma perchè li rendono così incomprensibili 'sti manuali? Mica siamo tutti ingegneri informatici!

Grep sta per general regular expression print. E' una specie di filtro. Io gli dico di trovare delle stringhe in uno o più file di testo e "lui" li trova. Fa più o meno questo lavoro.



Ho iniziato ad interessarmi di grep quando un giorno,  trovandomi di fronte ad un'infinità di file di testo, non ricordavo più in quali tra questi avevo scritto determinate cose. Onde evitare di controllarli uno per uno mi sono servito di questo straordinario strumento.

La sintassi generale di grep è

grep [OPTIONS] PATTERN [FILE...]

Il mio intento non è quello di dire, in modo pedissequo, tutto ciò che si può fare con grep; E questo per una sola ragione: Non ne sarei capace. Mi limito perciò a riassumere quel poco che so con la speranza che possa ritornare utile a qualcuno.

Poniamo il caso che io abbia 30 file di testo e, tra questi, voglia trovare una determinata parola (stringa).

Le alternative, in questo caso, sono due:
a. leggere tutti i documenti (non è detto che trovi ciò che cerco, soprattutto se ho del vino con me)
b. usare grep

La sintassi, in questo caso, è la seguente

grep -r "Jonny" /home/bit3lux/Documenti

L'opzione -r sta per Recursive, cioè dico a grep di cercare la stringa anche nelle sottodirectory.

"Jonny" è la stringa che grep dovrà cercare tra i vari file di testi

/home/bit3lux/Documenti: dico a grep in quale directory cercare (in questo caso nella cartella Documenti)

Ecco cosa ne viene fuori:

/home/bit3lux/Documenti/bit3lux1.txt:Jonny il bello          detto lo spartano  
/home/bit3lux/Documenti/bit3lux1.txt:Jonny il brutto         detto il bello
/home/bit3lux/Documenti/bit3lux1.txt:Jonny Jonny             detto Jonny Jonny
/home/bit3lux/Documenti/bit3lux1.txt:Jonny stecca            detto Jonny palla
/home/bit3lux/Documenti/bit3lux1.txt:Jonny Pane              detto nutella
/home/bit3lux/Documenti/bit3lux1.txt:Jonny fresa             detto Pomodoro
/home/bit3lux/Documenti/bit3lux1.txt:Jonni 1+1               detto Jonny due
/home/bit3lux/Documenti/bit3lux1.txt:Jonny Alfa              detto anche Omega
/home/bit3lux/Documenti/bit3lux1.txt:Jonny più               detto anche meno
/home/bit3lux/Documenti/bit3lux2.txt:Jonny il bello   11-11-1911
/home/bit3lux/Documenti/bit3lux2.txt:Jonny il brutto  10-01-1900
/home/bit3lux/Documenti/bit3lux2.txt:Jonny Jonny      12-12-1901
/home/bit3lux/Documenti/bit3lux2.txt:Jonny stecca     10-10-1911
/home/bit3lux/Documenti/bit3lux2.txt:Jonny Pane       28-02-1913
/home/bit3lux/Documenti/bit3lux2.txt:Jonny fresa      12-12-1912

Da questo risultato si evince che la stringa cercata si trova in due file: bit3lux.txt e bit3lux2.txt

Una caratteristica dei sistemi operativi di tipo Unix (quindi anche Linux) è quella di essere Case sensitive, cioè sensibili alle maiuscole.  Nel nostro esempio, grep cercherà solo "Jonny" e non anche "jonny"

Per ovviare a questo problema ci viene incontro l'opzione "-i"; Aggiungendola, grep non farà più distinzione tra lettere minuscole e lettere maiuscole

grep -ir  "jonny" /home/bit3lux/Documenti

In questo caso grep cercherà la stringa jonny in qualunque modo essa sia scritta, cioè

JoNNY
jonNy
JOnny 
JONNY
e via dicendo.

Potrei essere interessato a conoscere quante volte la stringa cercata compaia in ciascun documento. A tal fine userò l'opzione -c.

grep -cir  "jonny" /home/bit3lux/Documenti

Avrò come risultato il seguente: 


/home/bit3lux/Documenti/tutorial-shell.txt:0
/home/bit3lux/Documenti/italia3.gif:0
/home/bit3lux/Documenti/bash.pdf:0
/home/bit3lux/Documenti/Processo esecutivo.odt:0
/home/bit3lux/Documenti/bit3lux1.txt:12
/home/bit3lux/Documenti/x.odt:0
/home/bit3lux/Documenti/tutorial-shell.pdf:0
/home/bit3lux/Documenti/.directory:0
/home/bit3lux/Documenti/bit3lux1.txt.nc:0
/home/bit3lux/Documenti/Unità.jpeg:0
/home/bit3lux/Documenti/italia bandiera.png:0
/home/bit3lux/Documenti/bit3lux2.txt:6
/home/bit3lux/Documenti/File di testo:0
/home/bit3lux/Documenti/bit3lux:0
/home/bit3lux/Documenti/bash.txt:0

Di rilievo è, infine, l'opzione -l; essa ci indica semplicemente i documenti in cui è contenuta la stringa. 

grep -lir  "jonny" /home/bit3lux/Documenti

Il risultato in questo caso è il seguente: 

/home/bit3lux/Documenti/bit3lux1.txt
/home/bit3lux/Documenti/bit3lux2.txt


 Fin qui ho parlato di ricerca di una stringa in più file di testo.

Ma, ovviamente, si può cercarla anche in un solo file. 

grep -ir  "jonny" /home/bit3lux/Documenti/bit3lux1.txt

Risultato:

Jonny il bello          detto lo spartano
Jonny il brutto         detto il bello
Jonny Jonny             detto Jonny Jonny
Jonny stecca            detto Jonny palla
Jonny Pane              detto nutella
Jonny fresa             detto Pomodoro
Jonni 1+1               detto Jonny due
Jonny Alfa              detto anche Omega
Jonny più               detto anche meno
JONNY
JoNNY
jOnNy


Anzichè indicare il percorso (nel mio caso /home/bit3lux/Documenti), ci si può spostare con cd nella directory interessata

cd Documenti

Ora, se si vuole  cercare la stringa in tutti i file di testo, avremo

grep -ir "Jonny" *.txt

Se la si vuole cercare in un solo file (nel mio caso la cerco in bit3lux1.txt)

grep -ir "Jonny" bit3lux1.txt

Nel caso la si voglia cercare in più file

grep -ir "Jonny" bit3lux1.txt bit3lux2.txt

E via dicendo.

Ultima nota di rilievo, per il momento, è l'opzione -v. L'opzione -v, in pratica, fa fare a grep una ricerca invertita, cioè stampa solo le linee che non contengono la stringa cercata.

Facciamo un esempio.

Poniamo che abbia un decumento di testo il cui contenuto sia

Jonny la ruspa
Peter il Falco
Marcuzzo il Bello

se digito la seguente riga di comando

grep -vi "Peter il Falco" file.txt

Avrò come risultato

1:Jonny la ruspa
3:Marcuzzo il Bello


 Come potete notare manca "Peter il Falco" :D

La prossima volta, se ci sarà, parlerò della combinazione di grep con altri comandi.

La verità è che ieri sera ho rivisto "Jonny stecchino" (ma non alla tv che non possiedo bensì sul pc :D)

Ciao :)

8 commenti:

  1. Grande Stecchino :D! Mi raccomando se vai a Palermo non rubare le banane!! ahhahahahaha LOL

    Ottimo post al bar ;)

    RispondiElimina
  2. Ora dobbiamo usare grep per rispondere finalmente alla domanda lasciata in sospeso nel film.

    Scusate... si po' sapere cu minghia era ca faceva u tacchinu? eh?

    $ grep tacchino JohnnyStecchino.txt

    RispondiElimina
  3. Ottimo post! Ho fatto un bel ripasso :) Ma la cosa più succosa è che possiamo usare grep con le espressioni regolari :D

    RispondiElimina
  4. @Lightuono
    Se lo dici anche tu, vuol dire che dovrò fare molto attenzione nella scelta della frutta; magari mangerò solo frutti di corbezzolo. Ma ci sono i corbezzoli a Palermo? XD

    @Idl3
    Caspita! Non ci avevo pensato. Finalmente, grazie a grep, scoprirò l'arcano mistero che mi tormenta da anni. :D

    @Mattux
    Grazie. :) Certo, le espressioni regolari. A tal proposito, per farsi un'idea, vi invito a leggere questa pagina.

    http://www.pluto.it/files/ildp/guide/abs/regexp.html

    RispondiElimina
  5. a palermo le banane sono sacre! Non rubate le banane! Lo dice un palermitano doc xD

    RispondiElimina
  6. @Picchio
    Ma LOL. Se primo avevo qualche dubbio, ora ho la certezza: Non toccate quelle banane! XD

    RispondiElimina
  7. Bit3Lux ma lo sai che il grep è stato oggetto di discussione al colloquio di oggi :D

    RispondiElimina
  8. @Lightuono
    Spero che questo post ti sia stato utile :)

    RispondiElimina