Come usare il comando grep su Linux

Pubblicato: 2022-01-29
Un prompt del terminale su un PC Linux.
Fatmawati Achmad Zaenuri/Shutterstock

Il comando Linux grep è un'utilità di corrispondenza di stringhe e modelli che visualizza le righe corrispondenti da più file. Funziona anche con output convogliato da altri comandi. Ti mostriamo come.

La storia dietro grep

Il comando grep è famoso nei circoli Linux e Unix per tre motivi. In primo luogo, è estremamente utile. In secondo luogo, la ricchezza di opzioni può essere schiacciante. In terzo luogo, è stato scritto durante la notte per soddisfare un'esigenza particolare. I primi due vanno a gonfie vele; il terzo è leggermente fuori.

Ken Thompson aveva estratto le funzionalità di ricerca delle espressioni regolari dall'editor ed (pronunciato ee-dee) e aveva creato un programmino, per uso personale, per cercare nei file di testo. Il suo capo dipartimento presso i Bell Labs, Doug Mcilroy, si avvicinò a Thompson e gli descrisse il problema che stava affrontando uno dei suoi colleghi, Lee McMahon.

10 comandi di base di Linux per principianti
CORRELATI 10 comandi Linux di base per principianti

McMahon stava cercando di identificare gli autori dei documenti federalisti attraverso l'analisi testuale. Aveva bisogno di uno strumento in grado di cercare frasi e stringhe all'interno di file di testo. Thompson trascorse circa un'ora quella sera rendendo il suo strumento un'utilità generale che poteva essere utilizzata da altri e lo ribattezzò grep . Ha preso il nome dalla stringa di comando ed g/re/p , che si traduce come "ricerca globale di espressioni regolari".

Puoi guardare Thompson parlare con Brian Kernighan della nascita di grep .

Ricerche semplici con grep

Per cercare una stringa all'interno di un file, passare il termine di ricerca e il nome del file sulla riga di comando:

grep dave /etc/password in una finestra di terminale
Annuncio pubblicitario

Vengono visualizzate le linee corrispondenti. In questo caso, è una singola riga. Il testo corrispondente viene evidenziato. Questo perché nella maggior parte delle distribuzioni grep è alias di:

 alias grep='grep --colour=auto'

Diamo un'occhiata ai risultati in cui ci sono più righe che corrispondono. Cercheremo la parola "Media" in un file di registro dell'applicazione. Poiché non possiamo ricordare se la parola è in minuscolo nel file di registro, utilizzeremo l'opzione -i (ignora maiuscole):

 grep -i Average geek-1.log 

Viene visualizzata ogni riga corrispondente, con il testo corrispondente evidenziato in ciascuna.

Possiamo visualizzare le righe non corrispondenti usando l'opzione -v (inverti corrispondenza).

 grep -v Mem geek-1.log 

Non ci sono evidenziazioni perché queste sono le righe non corrispondenti.

Annuncio pubblicitario

Possiamo far sì che grep sia completamente silenzioso. Il risultato viene passato alla shell come valore restituito da grep . Un risultato pari a zero significa che la stringa è stata trovata e un risultato pari a uno significa che non è stata trovata. Possiamo controllare il codice di ritorno usando $? parametri speciali:

 grep -q media geek-1.log
 eco $?
 grep -q howtogeek geek-1.log
 eco $? 

Ricerche ricorsive con grep

Per cercare tra directory e sottodirectory nidificate, utilizzare l'opzione -r (ricorsiva). Nota che non fornisci un nome file sulla riga di comando, devi fornire un percorso. Qui stiamo cercando nella directory corrente "." ed eventuali sottodirectory:

 grep -r -i memfree . 

L'output include la directory e il nome del file di ciascuna riga corrispondente.

Possiamo fare in modo che grep segua collegamenti simbolici usando l'opzione -R (dereferenziazione ricorsiva). Abbiamo un collegamento simbolico in questa directory, chiamato logs-folder . Punta a /home/dave/logs .

 ls -l cartella-logs 

Ripetiamo la nostra ultima ricerca con l'opzione -R (dereferenziazione ricorsiva):

 grep -R -i memfree . 

Il collegamento simbolico viene seguito e anche la directory a cui punta viene cercata da grep .

Alla ricerca di parole intere

Per impostazione predefinita, grep corrisponderà a una riga se la destinazione della ricerca appare in un punto qualsiasi di quella riga, anche all'interno di un'altra stringa. Guarda questo esempio. Cercheremo la parola "libero".

 grep -i free geek-1.log 

Annuncio pubblicitario

I risultati sono righe che contengono la stringa "free", ma non sono parole separate. Fanno parte della stringa "MemFree".

Per forzare grep in modo che corrisponda solo a "parole" separate, usa l' -w (word regexp).

 grep -w -i free geek-1.log
 eco $? 

Questa volta non ci sono risultati perché il termine di ricerca "libero" non compare nel file come una parola separata.

Utilizzo di più termini di ricerca

L'opzione -E (extended regexp) consente di cercare più parole. (L'opzione -E sostituisce la versione obsoleta egrep di grep .)

Questo comando cerca due termini di ricerca, "media" e "memfree".

 grep -E -w -i "media|memfree" geek-1.log 

Annuncio pubblicitario

Tutte le righe corrispondenti vengono visualizzate per ciascuno dei termini di ricerca.

Puoi anche cercare più termini che non sono necessariamente parole intere, ma possono essere anche parole intere.

L'opzione -e (modelli) consente di utilizzare più termini di ricerca sulla riga di comando. Stiamo utilizzando la funzione parentesi delle espressioni regolari per creare un modello di ricerca. Dice a grep di trovare una corrispondenza con uno qualsiasi dei caratteri contenuti tra parentesi "[]". Ciò significa che grep corrisponderà a "kB" o "KB" durante la ricerca.

Entrambe le stringhe sono abbinate e, in effetti, alcune righe contengono entrambe le stringhe.

Linee di corrispondenza esattamente

-x (line regexp) corrisponderà solo alle righe in cui l' intera riga corrisponde al termine di ricerca. Cerchiamo un timbro di data e ora che sappiamo appare solo una volta nel file di registro:

 grep -x "20-gennaio--06 15:24:35" geek-1.log 

La singola riga che corrisponde viene trovata e visualizzata.

L'opposto è mostrare solo le linee che non corrispondono. Questo può essere utile quando stai guardando i file di configurazione. I commenti sono fantastici, ma a volte è difficile individuare le impostazioni effettive tra tutte. Ecco il /etc/sudoers :

Annuncio pubblicitario

Possiamo filtrare efficacemente le righe di commento in questo modo:

 sudo grep -v "#" /etc/sudoers 

È molto più facile da analizzare.

Visualizzazione solo del testo corrispondente

Potrebbe esserci un'occasione in cui non vuoi vedere l'intera riga corrispondente, solo il testo corrispondente. L'opzione -o (solo corrispondenza) fa proprio questo.

 grep -o MemFree geek-1.log 

La visualizzazione si riduce a mostrare solo il testo che corrisponde al termine di ricerca, invece dell'intera riga corrispondente.

Conteggio con grep

grep non riguarda solo il testo, può anche fornire informazioni numeriche. Possiamo far contare grep per noi in diversi modi. Se vogliamo sapere quante volte un termine di ricerca appare in un file, possiamo usare l'opzione -c (count).

 grep -c media geek-1.log 

grep segnala che il termine di ricerca appare 240 volte in questo file.

Puoi fare in modo che grep visualizzi il numero di riga per ogni riga corrispondente usando l'opzione -n (numero di riga).

 grep -n Jan geek-1.log 

Annuncio pubblicitario

Il numero di riga per ciascuna riga corrispondente viene visualizzato all'inizio della riga.

Per ridurre il numero di risultati visualizzati, utilizzare l'opzione -m (conteggio massimo). Limiteremo l'output a cinque righe corrispondenti:

 grep -m5 -n Jan geek-1.log 

Aggiunta di contesto

Essere in grado di vedere alcune righe aggiuntive, possibilmente righe non corrispondenti, per ciascuna riga corrispondente è spesso utile. può aiutare a distinguere quali delle linee abbinate sono quelle che ti interessano.

Per mostrare alcune righe dopo la riga corrispondente, utilizzare l'opzione -A (dopo il contesto). Stiamo chiedendo tre righe in questo esempio:

 grep -A 3 -x "20-gennaio-06 15:24:35" geek-1.log 

Per vedere alcune righe prima della riga corrispondente, utilizzare l'opzione -B (contesto prima).

 grep -B 3 -x "20-gennaio-06 15:24:35" geek-1.log 

E per includere le righe prima e dopo la riga corrispondente, utilizzare l'opzione -C (contesto).

 grep -C 3 -x "20-gennaio-06 15:24:35" geek-1.log 

Visualizzazione dei file corrispondenti

Per visualizzare i nomi dei file che contengono il termine di ricerca, utilizzare l'opzione -l (file con corrispondenza). Per scoprire quali file di codice sorgente C contengono riferimenti al file di intestazione sl.h , utilizzare questo comando:

 grep -l "sl.h" *.c 

Vengono elencati i nomi dei file, non le righe corrispondenti.

Annuncio pubblicitario

E, naturalmente, possiamo cercare i file che non contengono il termine di ricerca. L'opzione -L (file senza corrispondenza) fa proprio questo.

 grep -L "sl.h" *.c 

Inizio e fine righe

Possiamo forzare grep a visualizzare solo le corrispondenze che si trovano all'inizio o alla fine di una riga. L'operatore dell'espressione regolare "^" corrisponde all'inizio di una riga. Praticamente tutte le righe all'interno del file di registro conterranno spazi, ma cercheremo le righe che hanno uno spazio come primo carattere:

 grep "^ " geek-1.log 

Vengono visualizzate le righe che hanno uno spazio come primo carattere, all'inizio della riga.

Per abbinare la fine della riga, utilizzare l'operatore di espressione regolare "$". Cercheremo le righe che terminano con "00".

 grep "00$" geek-1.log 

Il display mostra le righe che hanno "00" come caratteri finali.

Utilizzo di pipe con grep

Ovviamente, puoi reindirizzare l'input a grep , reindirizzare l'output da grep a un altro programma e avere grep annidato nel mezzo di una catena di pipe.

Annuncio pubblicitario

Diciamo che vogliamo vedere tutte le occorrenze della stringa "ExtractParameters" nei nostri file di codice sorgente C. Sappiamo che ce ne saranno parecchi, quindi convogliamo l'output in less :

 grep "ExtractParameters" *.c | meno 

L'output è presentato in less .

Ciò ti consente di sfogliare l'elenco dei file e di utilizzare la funzione less's .

Se eseguiamo il pipe dell'output da grep in wc e utilizziamo l'opzione -l (lines), possiamo contare il numero di righe nei file di codice sorgente che contengono "ExtractParameters". (Potremmo ottenere questo risultato usando l'opzione grep -c (count), ma questo è un modo accurato per dimostrare il pipe out da grep .)

 grep "ExtractParameters" *.c | wc -l 

Con il comando successivo, eseguiamo il pipe dell'output da ls in grep e il pipe dell'output da grep in sort . Stiamo elencando i file nella directory corrente, selezionando quelli con la stringa "Aug" al loro interno e ordinandoli in base alla dimensione del file:

 ls -l | grep "Agosto" | ordina +4n 

Analizziamolo:

  • ls -l : esegue un elenco in formato lungo dei file utilizzando ls .
  • grep "Aug" : Seleziona le righe dall'elenco ls che contengono "Aug". Nota che questo troverebbe anche i file che hanno "Aug" nei loro nomi.
  • sort +4n : ordina l'output da grep sulla quarta colonna (dimensione file).

Otteniamo un elenco ordinato di tutti i file modificati ad agosto (indipendentemente dall'anno), in ordine crescente di dimensione del file.

CORRELATI: Come usare Pipes su Linux

grep: Meno comando, più alleato

grep è uno strumento fantastico da avere a tua disposizione. Risale al 1974 e va ancora forte perché abbiamo bisogno di quello che fa e niente lo fa meglio.

Accoppiare grep con alcune espressioni regolari-fu lo porta davvero al livello successivo.

CORRELATI: Come utilizzare le espressioni regolari di base per cercare meglio e risparmiare tempo

CORRELATI: I migliori laptop Linux per sviluppatori e appassionati