Come usare il comando grep su Linux

Un prompt terminale su un PC Linux.
Fatmawati Achmad Zaenuri / Shutterstock

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

La storia dietro grep

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

Ken Thompson aveva estratto le capacità di ricerca delle espressioni regolari da ed editore (pronunciato ee-dee) e ha creato un piccolo programma – per il suo uso personale – per cercare file di testo. Il suo capo dipartimento alla Bell Labs, Doug Mcilroy, si avvicinò a Thompson e descrisse il problema che uno dei suoi colleghi, Lee McMahon, stava affrontando.

McMahon stava cercando di identificare gli autori dei giornali federalisti attraverso un'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 trasformando il suo strumento in un'utilità generale che poteva essere utilizzata da altri e ribattezzata come grep. Ha preso il nome dal ed stringa di comando g/re/p , che si traduce come “ricerca globale di espressioni regolari”.

Puoi vedere 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 un terminale widnow

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

alias grep='grep --colour=auto'

Diamo un'occhiata ai risultati in cui sono presenti più righe corrispondenti. 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 il -i (ignora caso) opzione:

grep -i Average geek-1.log

grep -i Media geek-1.log nella finestra di un terminale

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

Output da grep -i Average geek-1.log in una finestra di terminale

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

grep -v Mem geek-1.log

grep -v Mem geek-1.log in una finestra terminale

Non viene evidenziato perché si tratta di linee non corrispondenti.

output da grep -v Mem geek-1.log in una finestra terminale

Possiamo causare grep essere completamente silenzioso. Il risultato viene passato alla shell come valore di ritorno da grep. Un risultato pari a zero indica la stringa era trovato e un risultato di uno significa che non era trovato. Possiamo controllare il codice di ritorno usando il $? parametri speciali:

grep -q average geek-1.log
echo $?
grep -q howtogeek geek-1.log
echo $?

grep -q media geek-1.log in una finestra terminale

Ricerche ricorsive con grep

Per cercare tra le directory e le sottodirectory nidificate, utilizzare l'opzione -r (ricorsiva). Tieni presente che non fornisci un nome file sulla riga di comando, devi fornire un percorso. Qui stiamo cercando nella directory corrente “.” e tutte le sottodirectory:

grep -r -i memfree .

grep -r -i memfree. in una finestra terminale

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

output da grep -r -i memfree. in una finestra terminale

Possiamo fare grep seguire i collegamenti simbolici usando il -R (dereference ricorsivo) opzione. Abbiamo un link simbolico in questa directory, chiamato logs-folder. Indica /home/dave/logs.

ls -l logs-folder

ls -l cartella-log in una finestra terminale

Ripetiamo la nostra ultima ricerca con il -R (dereference ricorsivo) opzione:

grep -R -i memfree .

grep -R -i memfree. in una finestra terminale

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

Uscita da grep -R -i memfree. in una finestra terminale

Alla ricerca di parole intere

Di default, grep corrisponderà a una riga se il target di ricerca appare in qualsiasi punto di quella riga, incluso all'interno di un'altra stringa. Guarda questo esempio. Cercheremo la parola “gratis”.

grep -i free geek-1.log

grep -i free geek-1.log in una finestra terminale

I risultati sono linee che contengono la stringa “libera”, ma non sono parole separate. Fanno parte della stringa “MemFree”.

Output da grep -i free geek-1.log in una finestra terminale

Forzare grep per abbinare solo “parole” separate, utilizzare il -w (parola regexp) opzione.

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

grep -w -i geek-1.log gratuito in una finestra terminale

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

Utilizzo di più termini di ricerca

Il -E (regexp esteso) consente di cercare più parole. (Il -E L'opzione sostituisce il deprecato egrep versione di grep.)

Questo comando cerca due termini di ricerca, “medio” e “memfree”.

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

grep -E -w -i "media | memfree" geek-1.log in una finestra terminale

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

Output da grep -E -w -i "media | memfree" geek-1.log in una finestra terminale

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

Il -e (pattern) consente di utilizzare più termini di ricerca nella riga di comando. Stiamo utilizzando la funzione di parentesi di espressione regolare per creare un modello di ricerca. Racconta grep per abbinare uno qualsiasi dei caratteri contenuti tra parentesi “()”. Questo significa grep corrisponderà a “kB” o “KB” durante la ricerca.

grep -e MemFree -e (kK) B geek-1.log in una finestra terminale

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

Uscita da grep -e MemFree -e (kK) B geek-1.log in una finestra terminale

Linee corrispondenti esattamente

Il -x (line regexp) corrisponderà solo alle righe in cui il linea intera corrisponde al termine di ricerca. Cerchiamo una data e un timestamp che sappiamo apparire solo una volta nel file di registro:

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

grep -x "20-gen - 06 15:24:35" geek-1.log in una finestra terminale

La singola riga corrispondente viene trovata e visualizzata.

L'opposto di ciò sta solo mostrando le linee che non fare incontro. 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 file:

Contenuto del file / etc / sudoers in una finestra del terminale

Siamo in grado di filtrare efficacemente le righe di commento in questo modo:

sudo grep -v "#" /etc/sudoers

sudo grep -v "#" / etc / sudoers in una finestra terminale

È molto più facile da analizzare.

Visualizza solo il testo corrispondente

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

grep -o MemFree geek-1.log

grep -o MemFree geek-1.log in una finestra terminale

La visualizzazione è ridotta per mostrare solo il testo corrispondente al termine di ricerca, anziché l'intera riga corrispondente.

output da grep -o MemFree geek-1.log in una finestra terminale

Conteggio con grep

grep non si tratta solo di testo, ma può anche fornire informazioni numeriche. Possiamo fare grep conta per noi in diversi modi. Se vogliamo sapere quante volte appare un termine di ricerca in un file, possiamo usare il -c (conta) opzione.

grep -c average geek-1.log

grep -c media geek-1.log in una finestra terminale

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

Tu puoi fare grep visualizzare il numero di riga per ogni riga corrispondente utilizzando il -n (numero riga) opzione.

grep -n Jan geek-1.log

grep -n jan geek-1.log in una finestra terminale

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

Output da grep -n jan geek-1.log in una finestra terminale

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

grep -m5 -n Jan geek-1.log

grep -m5 -n Jan geek-1.log in una finestra terminale

Aggiunta del contesto

Essere in grado di vedere alcune linee aggiuntive – possibilmente linee non corrispondenti – per ogni linea corrispondente è spesso utile. può aiutare a distinguere quali delle linee abbinate sono quelle a cui sei interessato.

Per mostrare alcune righe dopo la riga corrispondente, usa l'opzione -A (dopo il contesto). In questo esempio chiediamo tre righe:

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

grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log in una finestra terminale

Per vedere alcune righe prima della riga corrispondente, usa il -B (contesto precedente) opzione.

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

grep -B 3 -x "20-Jan-06 15:24:35" geek-1.log in una finestra terminale

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

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

grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log in una finestra terminale

Visualizzazione dei file corrispondenti

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

grep -l "sl.h" *.c

grep -l "sl.h" * .c in una finestra terminale

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

Uscita da grep -l "sl.h" * .c in una finestra terminale

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

grep -L "sl.h" *.c

grep -L "sl.h" * .c in una finestra terminale

Inizio e fine delle righe

Possiamo forzare grep per visualizzare solo le corrispondenze che sono all'inizio o alla fine di una riga. L'operatore di espressione regolare “^” corrisponde all'inizio di una riga. Praticamente tutte le linee all'interno del file di registro conterranno spazi, ma cercheremo le linee che hanno uno spazio come primo carattere:

grep "^ " geek-1.log

grep "^" geek-1.log in una finestra terminale

Vengono visualizzate le linee che hanno uno spazio come primo carattere — all'inizio della linea.

Output grep "^" geek-1.log in una finestra terminale

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

grep "00$" geek-1.log

grep "00 $" geek-1.log in una finestra terminale

Il display mostra le linee che hanno “00” come caratteri finali.

output di grep "00 $" geek-1.log in una finestra terminale

Utilizzo di Pipes con grep

Ovviamente, puoi reindirizzare l'input a grep , reindirizza l'output da grep in un altro programma, e avere grep incastonato nel mezzo di una catena di tubi.

Supponiamo di voler vedere tutte le occorrenze della stringa “ExtractParameters” nei nostri file di codice sorgente C. Sappiamo che ce ne saranno parecchi, quindi inseriamo l'output less:

grep "ExtractParameters" *.c | less

grep "ExtractParameters" * .c | meno in una finestra terminale

L'output è presentato in less.

Output da grep "ExtractParameters" * .c | meno in una finestra terminale

Ciò consente di sfogliare l'elenco dei file e di utilizzarlo less's funzione di ricerca.

Se eseguiamo il pipe dell'output da grep in wc e usa il -l (righe), possiamo contare il numero di righe nei file del codice sorgente che contengono “ExtractParameters”. (Potremmo raggiungere questo obiettivo usando il grep -c (conta) opzione, ma questo è un modo semplice per dimostrare il piping di grep.)

grep "ExtractParameters" *.c | wc -l

grep "ExtractParameters" * .c | wc -l in una finestra terminale

Con il comando successivo, stiamo eseguendo il piping dell'output da ls in grep e convoglia l'output da grep in sort . Stiamo elencando i file nella directory corrente, selezionando quelli con la stringa “Aug” in essi e ordinandoli per dimensione del file:

ls -l | grep "Aug" | sort +4n

ls -l | grep "ago" | ordina + 4n in una finestra del terminale

Analizziamo questo:

  • ls -l: Esegue un elenco di formati lunghi dei file utilizzando ls.
  • grep “ago”: Selezionare le linee da ls elenco che contiene “Aug”. Si noti che questo troverebbe anche i file che hanno “Aug” nei loro nomi.
  • ordina + 4n: Ordina l'output da grep sulla quarta colonna (dimensione file).

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

RELAZIONATO: Come usare le pipe su Linux

grep: meno un comando, più di un alleato

grep è uno strumento eccezionale da avere a tua disposizione. Risale al 1974 ed è ancora forte perché abbiamo bisogno di ciò che fa, e niente lo fa meglio.

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

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

Articoli correlati

Ultimi articoli