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.
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:
- La locale di sistema: di default grep interpreta i byte come caratteri UTF-8, e questo comporta lavoro di decodifica per ogni byte. Su dati puramente ASCII (la maggior parte di log e file sorgente) è inutile.
-
La sintassi del pattern: una regex
-F(stringa letterale) è più veloce di una BRE, che è più veloce di una ERE, che è più veloce di una PCRE. Scegli sempre il livello più semplice che basta.
Il trucco classico per velocizzare grep su grandi file ASCII è impostare la locale
a C per la durata del comando:
$ 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.
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:
| flag | cosa fa |
|---|---|
| -a | tratta i binari come testo (stampa comunque le righe) |
| -I | salta 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:
$ 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:
| tool | comando | punto di forza |
|---|---|---|
| ripgrep | rg | il più veloce; rispetta .gitignore di default |
| the silver searcher | ag | simile a rg, popolare prima di lui |
| ack | ack | il pioniere, scritto in Perl, ottimo per i sorgenti |
$ 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.
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:
- Usa
grepquando: stai filtrando una pipe (ps | grep,tail -f | grep), lavori su un singolo file conosciuto, stai scrivendo uno script destinato a girare su macchine altrui dove grep c'è sempre. - Usa
rgquando: cerchi dentro un albero di codice sorgente. È drasticamente più veloce, ha esclusioni intelligenti di default, l'output è già colorato bene e formattato per i sorgenti.
Installazione di ripgrep in una riga:
# 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:
| grep | ripgrep | nota |
|---|---|---|
| -i | -i | case insensitive |
| -v | -v | invertito |
| -w | -w | word boundary |
| -A/-B/-C N | -A/-B/-C N | contesto, identico |
| --include='*.py' | -tpy | rg riconosce 100+ tipi di file per nome |
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.