$ grep — corso
Lezione 10 di 10 · finale

Performance, binari, e alternative moderne

Le ultime cose da sapere per usare grep come un veterano: rendere le ricerche veloci sul serio, sopravvivere ai file binari, e capire quando vale la pena passare a uno dei successori — ripgrep in testa.

Teoria

Cosa rallenta grep, e cosa lo accelera

Grep è già di per sé velocissimo. Ma su file molto grandi (gigabyte) o ricorrendo su alberi enormi di codice, due fattori incidono in modo sproporzionato:

Il trucco classico per velocizzare grep su grandi file ASCII è impostare la locale a C per la durata del comando:

LC_ALL=C
$ time grep "ERROR" enorme.log
real    0m4.380s

$ time LC_ALL=C grep "ERROR" enorme.log
real    0m1.220s

Su file ASCII puri lo speedup è da 2× a 5×. Su file che contengono caratteri non-ASCII (testi multilingua, simboli) non usarlo: grep tratterebbe i byte uno per uno e potrebbe trovare match parziali sbagliati o saltarne di validi.

Pratica

File binari, e poi: le alternative

Quando grep incontra un file binario (con byte NUL al suo interno), il comportamento di default è prudente: stampa Binary file XYZ matches invece di mostrare le righe, per non sporcare il terminale con caratteri di controllo. Tre flag governano questo aspetto:

flagcosa fa
-atratta i binari come testo (stampa comunque le righe)
-Isalta del tutto i file binari
--binary-files=...controllo fine: binary, text, without-match

L'uso più comune nelle ricerche ricorsive è -I per evitare che grep perda tempo (e sporchi l'output) sui PDF, le immagini, gli eseguibili:

solo file di testo
$ grep -rnI "TODO" .
# nessun "Binary file ... matches" sparso nell'output

Alternative moderne

Negli ultimi 10-15 anni sono nati strumenti pensati esplicitamente per cercare in cartelle di codice: più veloci di grep su quel tipo specifico di lavoro, con esclusioni intelligenti di default. I tre principali, in ordine di diffusione attuale:

toolcomandopunto di forza
ripgreprgil più veloce; rispetta .gitignore di default
the silver searcheragsimile a rg, popolare prima di lui
ackackil pioniere, scritto in Perl, ottimo per i sorgenti
stessa ricerca, tre strumenti
$ grep -rnI --exclude-dir={.git,node_modules,dist} "calculatePrice" .
$ ag "calculatePrice"
$ rg "calculatePrice"

rg e ag conoscono già .gitignore, sanno saltare i binari, distinguono i file di codice e mostrano nomi/numeri di riga di default. La sintassi delle regex è leggermente diversa (entrambi usano regex Rust/PCRE-like), ma per l'uso quotidiano è sovrapponibile a grep.

Trucco

Quando passare a ripgrep (e quando restare con grep)

Vale la pena conoscere entrambi e usarli ciascuno per quel che fanno meglio. Una regola pratica che funziona:

Installazione di ripgrep in una riga:

installazione
# macOS
$ brew install ripgrep

# Debian / Ubuntu
$ sudo apt install ripgrep

# Arch
$ sudo pacman -S ripgrep

# Fedora
$ sudo dnf install ripgrep

Cinque opzioni di rg da conoscere subito, perché si mappano in modo pulito a quelle di grep che hai imparato in questo corso:

grepripgrepnota
-i-icase insensitive
-v-vinvertito
-w-wword boundary
-A/-B/-C N-A/-B/-C Ncontesto, identico
--include='*.py'-tpyrg riconosce 100+ tipi di file per nome
Conclusione del corso: grep non sta scomparendo. È presente ovunque, dai server più vecchi ai container più nuovi, ed è il linguaggio comune per la ricerca testuale in tutto l'ecosistema Unix. Anche se nella tua vita quotidiana userai rg il 70% delle volte, le ore investite per conoscere bene grep si ripagano ogni volta che apri un terminale su una macchina che non è la tua.

Buona caccia ai pattern.