$ grep — corso
Lezione 02 di 10

Le basi: pattern, file e flag

Otto opzioni coprono il novanta per cento degli usi reali di grep. Impararle a memoria, insieme al concetto di exit code, vuol dire essere autosufficienti per quasi tutto il resto.

Teoria

Sintassi, comportamento, exit code

La forma generale di grep è semplice:

forma generale
grep [OPZIONI] PATTERN [FILE...]

Se non si passa alcun file, grep legge dallo standard input — è la chiave del suo uso in pipe, che vedremo nella lezione 9. Quando i file sono più di uno, grep antepone ad ogni riga il nome del file di provenienza.

Le opzioni che bastano per la stragrande maggioranza dei casi reali sono otto:

opzionecosa fa
-iignora maiuscole/minuscole
-nmostra il numero di riga davanti al match
-cconta le righe che matchano (non i match!)
-vinverte: mostra le righe che NON matchano
-lstampa solo i nomi dei file che contengono almeno un match
-Ll'opposto di -l: i file che NON hanno nessun match
-wmatch solo se è una parola intera
-xmatch solo se l'intera riga corrisponde

Una nona, fondamentale per gli script, è -q (quiet): grep non stampa nulla e termina al primo match. Serve solo per leggere il suo exit code, che è il modo con cui grep comunica il risultato a chi lo chiama:

Pratica

Le otto opzioni viste in azione

Mettiamo in piedi un file più sostanzioso e proviamole tutte di seguito:

~/lezione02
$ cat > access.log <<'EOF'
2026-05-20 10:01 GET /home 200
2026-05-20 10:02 POST /login 200
2026-05-20 10:03 GET /home 404
2026-05-20 10:04 GET /api/users 500
2026-05-20 10:05 GET /home 200
EOF

# -n : numerare le righe
$ grep -n 404 access.log
3:2026-05-20 10:03 GET /home 404

# -c : quante righe corrispondono
$ grep -c GET access.log
4

# -v : tutto tranne le richieste con status 200
$ grep -v 200 access.log
2026-05-20 10:03 GET /home 404
2026-05-20 10:04 GET /api/users 500

# -i : maiuscole/minuscole indifferenti
$ grep -i post access.log
2026-05-20 10:02 POST /login 200

Ora un caso classico in cui -w salva la vita. Cerchiamo la parola log in un file di configurazione: senza -w matcheremmo anche login, logout, logger

match di parola intera
$ printf '%s\n' "log=on" "login=true" "log_level=info" | grep log
log=on
login=true
log_level=info

$ printf '%s\n' "log=on" "login=true" "log_level=info" | grep -w log
log=on
Trucco

grep -q negli script: il rilevatore silenzioso

Quando vuoi solo sapere se un certo testo c'è dentro un file — senza vedere il match, senza output — il pattern ideale negli shell script è grep -q. È più pulito e più veloce di tutte le alternative.

setup-server.sh
# prima di aggiungere una riga a /etc/hosts, controlla che non ci sia già
if grep -q "^192\.168\.1\.10" /etc/hosts; then
  echo "host già presente"
else
  echo "192.168.1.10 server-locale" | sudo tee -a /etc/hosts
fi

# controlla se un servizio è attivo
if ps aux | grep -q "[n]ginx"; then
  echo "nginx attivo"
fi
Sul perché [n]ginx invece di nginx: è uno dei trucchi più amati. La regex [n]ginx matcha esattamente la stringa nginx, ma il comando grep stesso nella sua riga del ps contiene [n]ginx, non nginx, e quindi non si auto-trova. Risultato: niente "grep grep" da escludere a mano. Lo riprenderemo nella lezione 9.

Combinazione utilissima con -l: trovare in quali file di una cartella compare un certo testo, ma ricevere solo l'elenco dei file, perfetto per pipare ad altri comandi:

solo i nomi dei file
$ grep -l "TODO" *.py
app.py
utils.py

# apri tutti i file che contengono TODO nel tuo editor
$ vim $(grep -l "TODO" *.py)