Come si usa il comando linux grep? questo comando è sicuramente molto conosciuto nell’ambiente degli utenti di sistemi linux/unix come ubuntu, mint, debian. Ricordiamoci inoltre che anche i sistemi apple rientrano in questa famiglia, quindi grep è presente anche sul terminale del vostro Imac o macbook con macos e osx.
Grep serve a cercare testo. Permette di cercare una parola o una serie di parole all’interno di uno o più file. Come vedremo si può utilizzare sia passando come argomento un file, sia inserendo grep in una pipe di comandi, filtrando quindi l’output di un comando.
Grep è usato spesso in bash per estrarre righe da file e cartelle e processarle o scriverle su un altro file
Sommario
- Da dove viene il nome grep?
- Estrarre righe da un file
- Cercare solo parole intere
- Grep case insensitive – ignorare maiuscole e minuscole
- Ricerca multipla di più parole
- Ricerca ricorsiva
- Contare le righe trovate
- Grep con numero di riga delle corrispondenze
- Ricerca inversa – escludere una stringa
- Vedere righe prima e dopo il match
- Grep e pipe
- Estrarre solo i nomi dei file contenenti la stringa
- Grep color – colorare i match
- Quiet mode – grep -q
- Conclusioni
Da dove viene il nome grep?
Il nome “grep” deriva a quanto pare da un comando proprio dell’editor unix/linux “ed” che ha una funzione simile. Si tratta di:
g/re/p
Del comando grep esistono diverse varianti, come fgrep, grep, egrep. Nella maggior parte dei casi si potrebbe utilizzare fgrep per ragioni di velocità. La pigrizia e l’abitudine però portano ad utilizzare nella maggior parte dei casi il più corto e più veloce da digitare grep.
Vedremo grep per esempi per discutere meglio le caratteristiche delle diverse “grep options” caso per caso.
Estrarre righe da un file
Se avete un file di testo e volete ricercare righe che contengano una determinata stringa potete usare grep nella sua forma più semplice e lineare:
grep user /etc/passwd
con questo comando stiamo cercando la stringa user all’interno del file /etc/passwd, un possibile output sarà:
Cercare solo parole intere
La modalità di default di grep è quella di ricercare la stringa impostata all’interno del testo, comprendendo anche i casi in cui la stringa fa parte di una parola più grande. Questo potrebbe non essere sempre il comportamento voluto. Ci viene quindi in aiuto l’opzione -w
che indica al comando di cercare la stringa solamente quando compone una parola intera. Vediamo un comando grep di esempio:
grep -w capita testo.txt
in questo caso otterremo solamente le righe in cui capita è usato come parola intera, saranno quindi escluse le righe che ad esempio contengono capitano o capitanato.
grep case insensitive – ignorare maiuscole e minuscole
Il comportamento predefinito di grep è, come solito nell’ambiente linux/unix, quello di fare distinzione fra maiuscole e minuscole. Possiamo cambiare questo comportamento, in grep l’opzione -i
serve proprio a dire a grep di effettuare la ricerca in modo case insensitive.
grep -i "user" /etc/passwd
questo comando cercherà user, ma anche User, USER, UsEr ecc…
grep ricerca multipla di più parole
Nella maggior parte dei casi grep viene usato per cercare una singola parola in uno o più file. Può capitare però di voler cercare più di una parola.
Se ad esempio vogliamo le righe che contengono user e quelle che contengono root, possiamo usare il comando
egrep 'user|root'/etc/passwd
In questo caso abbiamo utilizzato egrep, perché abbiamo bisogno delle funzionalità estese che questa variante ci offre. Per specificare le due stringhe le abbiamo separate con il simbolo della pipe | e abbiamo racchiuso tutto fra virgolette singole.
Possiamo specificare anche più di due stringhe di ricerca, come nell’esempio della figura:
grep ricerca ricorsiva
Possiamo usare grep anche in maniera ricorsiva, ovvero specificando una cartella invece di un singolo file. Il comando grep eseguirà la ricerca sulla cartella specificata e in tutte le sue sottocartelle.
Per fare questo dovremo aggiungere l’opzione -r
e, come abbiamo detto, specificare una cartella invece di un singolo file. Vediamo un esempio:
grep -r informaticappunti /home/user/informaticappunti/
Come vediamo grep ci indica il percorso e il nome del file che contiene la stringa e poi la riga in cui è contenuta. Se non vogliamo che grep includa i nomi dei file possiamo aggiungere l’opzione -h
eseguendo quindi il comando
grep -h -r informaticappunti /home/user/informaticappunti/
le due opzioni possono essere accorpate ottenendo
grep -hr informaticappunti /home/user/informaticappunti/
Contare le righe trovate
In alcuni casi potrebbe essere necessario contare il numero di righe che corrispondono ai criteri di ricerca. Per fare questo possiamo utilizzare l’opzione grep -c
. Eseguendo il comando
grep -c user /etc/passwd
avremo in risposta il numero 3, che come abbiamo visto negli esempi precedenti è il numero di righe che contengono la string user nel file /etc/passwd
Grep con numero di riga delle corrispondenze
In alcuni casi può essere necessario, dopo la ricerca con grep, andare a ricercare manualmente le righe nel file, magari per modificarle o cancellarle. In questa evenienza il comando grep può venirci in aiuto specificando il numero della riga in cui ha trovato la stringa che abbiamo cercato. Basterà usare l’opzione -n
per ottenere ciò che vogliamo.
grep -n user /etc/passwd
l’output in questo caso sarà simile a questo
In questo esempio grep ci comunica che ha trovato la parola cercata alle righe 29, 37 e 41. Non dovremo quindi impazzire a ricercarle con vi, vim o nano.
Grep ricerca inversa – escludere una stringa
Con il comando grep è possibile anche invertire al logica di ricerca. In questo modo quindi grep cercherà tutte le righe che non contengono la stringa specificata. Questo è un buon modo per eliminare delle righe da un file. L’opzione da usare in questo caso è -v
. Vediamo un esempio di grep -v
:
grep -v user /etc/passwd
Con questo comando riceveremo in output tutte le righe del file /etc/passwd che non contengono la stringa user.
Vedere righe prima e dopo il match
In alcuni casi è utile farsi stampare da grep anche qualche riga prima o dopo la riga contenente la stringa che stiamo cercando in modo da capire meglio il contesto in cui è presente. Per farlo sono presenti due diverse opzioni, una per indicare quante righe prima vogliamo vedere e l’altra per indicare quante righe dopo vogliamo che il comando grep ci mostri.
L’opzione grep -B
(Before) ci permette di indicare quante righe prima del match vogliamo vedere. Ad esempio
grep -B 3 error /var/log/mylog.log
Questo comando ci mostrerà tutte le righe che contengono la stringa error e le 3 righe precedenti per ognuno dei casi di match.
L’opzione grep -A
(After) ci permette di indicare quante righe dopo ogni match vogliamo vedere. Prendendo a modello l’esempio precedente:
grep -B 3 error /var/log/mylog.log
in questo caso il comando grep ci mostrerà tutte le righe che contengono la stringa error e le 3 righe successive ad ognuno dei casi di match.
Le due opzioni si possono combinare se vogliamo vedere sia righe prima che righe dopo. Combinando gli esempi precedenti otteniamo:
grep -A 3 -B 3 error /var/log/mylog.log
Come avremo già capito in questo caso otterremo tutte le righe che contengono la stringa error inseriti fra le tre righe precedenti e le tre righe successive.
Grep e pipe
Le pipe sono, in poche parole, un modo veloce per concatenare una serie di comandi in modo che l’output di un comando sia l’input del comando successivo.
Pipe e grep sono spesso usati insieme quando abbiamo un comando che restituisce molti risultati ma noi vogliamo vederne solo alcuni.
Un esempio molto utile della coppia pipe grep è il filtraggio dei risultati di apt. Quando cerchiamo infatti un pacchetto all’interno del famoso gestore di pacchetti è possibile che ci vengano fuori molti risultati. In questo caso possiamo usare grep per eseguire un’ulteriore scrematura dei risultati. Vediamo un esempio di questo utilizzo in cui grep fa un ottimo lavoro:
apt-cache search maria | grep server
se non utilizzassimo | grep server
ci troveremo davanti ad una lista piuttosto lunga in cui cercare il pacchetto server sarebbe piuttosto scocciante. Con l’aiuto di pipe e grep invece possiamo ridurre i risultati a solo poche righe.
In alcuni casi si usa la sequenza cat pipe grep per scrivere in maniera più leggibile dei comandi che potrebbero essere scritti semplicemente con grep.
cat /proc/cpuinfo | grep -i 'Model'
che potrebbe essere riscritto come
grep -i 'Model' /proc/cpuinfo
Molte persone utilizzano la prima versione in quanto la ritengono più leggibile (si intuisce di più il flusso di informazioni/operazioni leggi il file -> filtra le righe).
Grep estrarre solo i nomi dei file contenenti la stringa
Se avete bisogno di ottenere solamente i nomi dei file che contengono la stringa che state cercando potete utilizzare l’opzione -l
. Ad esempio:
grep -l 'main' *.java
che tirerà fuori tutti i nomi dei file che contengono main e hanno estensione .java
Grep color – colorare i match
Nelle figure vi sarà capitato di vedere che i match trovati vengono evidenziati in rosso. In questo caso accade perché l’opzione –color=auto è impostato di default in ubuntu e mac osx attraverso un alias. Se il vostro sistema operativo non esegue quest’operazione in automatico e il testo in output non viene evidenziato potete provare ad aggiungere manualmente l’opzione –color=always al vostro comando grep. Un comando di esempio sarà quindi:
grep --color=always user /etc/password
L’output in questo caso sarà lo stesso che abbiamo visto nel primo esempio del tutorial parlando del comando grep senza argomenti.
Questa opzione aiuta a riconoscere subito dove sono le stringhe trovate da grep, particolarmente utile se usate le opzioni per includere righe prima o dopo il match.
Oltre all’opzione --color
è disponibile anche la variabile della riga di comando GREP_COLOR
che permette di definire il colore che vogliamo impostare, aiutandoci in caso il colore predefinito non ci piaccia o sia poco visibile nei colori del tema del nostro terminale.
Maggiori informazioni su GREP_COLOR
possono essere trovate su gnu.org
Grep quiet mode – grep -q
In alcuni casi, specialmente se si utilizza grep all’interno di uno script bash, non abbiamo bisogno che grep ci stampi tutte le occorrenze della stringa cercata, ma vogliamo solamente sapere se è stata trovata o no. In questo caso ci viene in aiuto l’opzione -q
che possiamo anche scrivere come --quiet
o --silent
. Se accoppiamo questa opzione con un test sul risultato dell’ultima operazione possiamo vedere se la stringa è stata trovata. Vediamo un esempio:
echo "stringa di testo" | grep -q "testo"
echo $?
0
Nella prima riga abbiamo prodotto la stringa “string da testo” e poi mandandola in pipe a grep abbiamo cercato all’interno di essa la stringa testo utilizzando l’opzione -q. Apparentemente grep non ha prodotto alcun risultato, ma se subito dopo andiamo a farci mostrare il codice di uscita dell’ultimo comando otterremo 0. Questo ci indicherà che grep è terminato in modo corretto, ha quindi trovato almeno una volta la stringa che stavamo cercando.
Vediamo ora un esempio in cui non troviamo la stringa cercata:
echo "stringa di testo" | grep -q "altro testo"
echo $?
1
In questo caso, in “stringa di testo” abbiamo cercato di individuare “altro testo” che però non è presente. In questo caso quindi grep non terminerà in modo corretto e quindi il valore del codice di uscita (exit code) non sarà 0.
Conclusioni
Riassumiamo in breve tutte le opzioni viste in precedenza in un pratico schema:
Opzioni del comando linux grep | Descrizione |
---|---|
-w | Cerca solo le parole intere |
-i | Ignora la differenza fra maiuscole e minuscole |
-r | Ricerca ricorsiva nelle sottodirectory |
-h | Rimuovi dall’output il nome del file |
-c | Conta le righe trovate |
-n | Aggiunge il numero di riga nell’output |
-v | Ricerca inversa, esclude le righe che contengono il pattern |
-A n | Aggiunge all’output n righe dopo il match |
-B n | Aggiunge all’output n righe prima del match |
-l | Stampa solo i nomi dei file che contengono la stringa |
–color | Colora l’output di grep |
-q | Non mostrare l’output del comando (usato con test dell’exit-code) |
In conclusione il comando linux grep è un comando molto utilizzato e molto utile quando si utilizza la riga di comando o si scrivono script bash. Usare correntemente il terminale senza conoscere il comando grep è difficile, ma non sempre si conoscono tutte le varie opzioni per sfruttare al meglio questo comando.