Bad Daemons

Alternativas a grep

Desde hace un tiempo me he ido encontrando con la necesidad de buscar cadenas de texto (sin regex, solo palabras simples) en ficheros muy grandes o muchos ficheros pequeños. Para ello, siempre habia usado grep, pero a la fueron subiendo los GB en los que buscar, fue subiendo el tiempo que tenia que esperar, hasta niveles absurdos. Y de casualidad me encontré con un par de alternativas a grep mucho más rápidas.

La primera fue The Silver Search. En su gitsux lo comparan con ack, siendo ag una orden de magnitud más rápido. Está en los repositorios de casi todas las distros, el paquete se llama the_silver_searcher menos en Debian y derivados, que se llama silversearcher-ag. Este paquete me sirvió un tiempo, pero a medida que fue subiendo la cantidad de datos en los que necesitaba bucear, hasta ag se quedaba corto, por lo que terminé usando ripgrep.

Véamos una cutre-demostración de las tres alternativas. Primero, la fuente en la que bucear:

du -sh ~/.owncloud
36G /home/drymer/.owncloud

Ahí tengo 36GB de datos, como se puede ver. Véamos cuanto tarda en buscar grep la palabra documentos, cuanto ag y cuanto ripgrep:

time grep -ri documentos ~/.owncloud
time ag documentos ~/.owncloud
time rg documentos ~/.owncloud
grep --color -ri documentos ~/.owncloud > /dev/null  42,48s user 59,08s system 12% cpu 14:03,23 total
ag documentos ~/.owncloud > /dev/null                 2,98s user 10,81s system 2% cpu 8:01,56 total:
rg documentos ~/.owncloud > /dev/null                 1,64s user 1,30s system 20% cpu 14,534 total

Como se puede ver, grep tarda 14 minutos con un uso de la CPU de un 12%, ag tarda 8 minutos con un uso de la CPU del 2% y por último ripgrep, que tarda la friolera de 14 segundos, a costa de un mayor uso de la CPU, aunque es más que razonable. Para quien sienta curiosidad de ver por que es tan absurdamente rápido, en el repositorio lo explican, además de enlazar a un blog en el que hacen distintos benchmarks mucho más trabajados que el mío.

Ya solo queda instalar ripgrep. Por desgracia, no está en el repositorio de Debian, aunque si en muchos otras distros. Por ello, habrá que compilar o tirar de binario. Como está hecho en Rust y paso de meterme en ese mundo, he tirado de binario, que se puede instalar así:

wget https://github.com/BurntSushi/ripgrep/releases/download/0.5.2/ripgrep-0.5.2-i686-unknown-linux-musl.tar.gz -O /tmp/ripgrep.tar.gz
cd /tmp/
tar xzf /tmp/ripgrep.tar.gz
cd ripgrep-*
sudo mv rg /usr/local/bin