Uso avanzado de Find y Grep

Durante todos mis años de desarrollado LAMP, han habido una serie de comandos UNIX que me han sido muy útiles. En este artículo voy a compartir unos ejemplos de su uso que van más allá de su empleo básico, con el objetivo de que sirva de ayuda para otros desarrolladores. En esta ocasión voy a centrarme en find y grep, más adelante me gustaría ampliar este artículo con otros comandos que facilitan la vida al programador y al usuario de Unix / Linux en general.

Entrada, salida y su redireccionamiento

Antes de empezar, no estaría de más, para una mayor claridad de los ejemplos, explicar que en Unix el standard output (salida) e input (entrada) es la consola. Debemos tenerlo en cuenta para redireccionar tanto la salida como la entrada de datos de las órdenes mediante pipelines ( < > | )

find y grep

Grep es una poderosa herramienta que nos permite encontrar coincidencias dentro de un fichero o de un conjunto de ellos, gran parte de sus “superpoderes” emanan de las expresiones regulares. A continuación, veamos unos ejemplos de su uso para búsquedas no muy elementales:

– En primer lugar, con grep hay que escapar los caracteres especiales:

grep "regex|regex not" borrame.txt  => grep "regex\|regex not" borrame.txt

– Si no se quiere escaparlos para que no los entienda como parte de la cadena buscada, debemos usar la opcion -E o bien egrep:

grep -E "regex|regex not" borrame.txt

egrep "regex|regex not" borrame.txt

– Para buscar una cadena de texto en ficheros filtrados recursivamente:

grep -r --include="*.php" "yorkshiresConfig.ini" * > resultados.txt

Esta orden buscaría recursivamente, a través de todos los subdirectorios, la cadena “yorkshiresConfig.ini” en todos los ficheros con extensión php.

El nombre de la orden find ya nos dice todo acerca de su función. Se vuelve realmente poderosa cuando se combina con otras órdenes. He aquí algunos ejemplos:

– Para borrar ficheros resultantes de una búsqueda de cierto tipo de ficheros, con los subdirectorios incluidos:

find -name '*.po' -exec rm -i {} \;

– Para borrar todos los ficheros que tengan más de 50 días:

find /compartido/backups/pro/auto/bd/* -mtime +50 -exec rm {} \;

Como fácilmente podemos acabar borrando lo que no deseábamos, con la opción -i el programa rm pedirá confirmación por cada fichero.

– Para moverlos a otro directorio:

find -name '*.po' -exec mv {} ./poBackups \;

– También podemos renombrar masivamente ficheros, el siguiente comando busca recursivamente todos los ficheros “.po” y los renombra a “.po.bak”:

find -name '*.po' | sed 's/\(.*\).po$/mv "&" "\1.po.bak"/' | sh

Si en vez de “find -name ‘*.po”‘ usáramos “ls -d *.po” serían sólo los directorios del directorio actual.

Busca en el directorio acutal y en los subdirectorios todos los ficheros con la extensión php que contengan la cadena “Possible reason: your host may have disabled the mail“:

find -name '*.php' -exec grep 'Possible reason: your host may have disabled the mail' {} \;

Cuando el listado de resultados es demasiado grande como para manejarlo cómodamente en el terminal, podemos redireccionar el resultado con una pipe desde el standard output a un fichero:

find -name '*.php' -exec grep 'Possible reason: your host may have disabled the mail' {} \; > results.txt

Si de cada fichero encontrado queremos saber su ruta exacta, debemos añadir “-print” al final:

find -name '*.php' -exec grep 'Possible reason: your host may have disabled the mail' {} \; -print

La orden find también nos permite buscar por fechas:

– Encontrar ficheros modificados en el último día:

find -ctime -1 -type f

– Para directorios:

find -ctime -1 -type d

– Encontrar ficheros más recientes que main.css:

find -newer main.css

Contar el número de ficheros de un directorio y subdirectorios:

find . -type f | wc -l

ls y mv al rescate

A veces, las herramientas más básicas son las adecuadas. Esto es especialmente cierto en UNIX, pues en su tradición está la filosofía de disponer de muchas pequeñas herramientas para tareas muy concretas, permitiendo al usuario combinarlas para conseguir objetivos más complejos.

–  Para contar los elementos del directorio actual podemos usar la orden wc (Word Count), en combinación con ls. El parámetro -l indica que cuente líneas en vez de palabras, por lo tanto, contará el número de líneas que devuelve ls:

ls -1 | wc -l

– Listar sólo los directorios, sin los ficheros, del directorio actual:

ls -d */

– Listar sólo los directorios de un subdirectorio:

ls -d Proyectos/*/

– Mover sólo los ficheros ocultos de un directorio (origen) a otro (dest):

mv origen/{*,.*} dest/

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.