Búsqueda de texto

No encuentro las cosas

Supongamos que queremos buscar un comando en nuestro sistema que se llama python (en este caso es un intérprete de python). Si conocemos su ubicación exacta, en este caso /usr/bin, es fácil listar los ficheros que cumplen nuestras restricciones usando el comando ls:

$ ls /usr/bin/python*

El problema es que los comandos de Linux se pueden distribuir por muchos directorios distintos y a veces no sabemos exactamente dónde están.

Find

El comando find es uno de los más importantes de Linux. Permite encontrar ficheros y directorios que encajan con una especificación dada que puede incluir desde el nombre, hasta fechas de modificación o los permisos que tiene asignados.

De forma intuitiva, podemos especificar el uso de este comando de la siguiente forma:

find <dónde comenzar la búsqueda> <criterio de búsqueda> <acciones a realizar>

En el ejemplo anterior, podemos utilizar el comando find indicando que busque en todo el directorio /usr de la siguiente forma:

$ find /usr -name python* -print
/usr/include/python2.6
/usr/share/doc/python-lockfile-0.8
/usr/share/doc/python-markdown-2.0.1
/usr/share/doc/m2crypto-0.20.2/demo/Zope/lib/python
...

En el ejemplo vemos el uso típico del comando. Primero indicamos que la búsqueda comience a partir del directorio /usr. Automáticamente find buscara también en todos los subdirectorios contenidos en el mismo. Seguidamente le proporcionamos un criterio de búsqueda mediante el parámetro -name, que indica el nombre de los ficheros a buscar. Finalmente le especificamos que la acción a realizar es mostrar los resultados en pantalla mediante el parámetro -print.

El resultado que se muestra no sólo nos indica los nombres de los comandos, sino también nos ofrece información sobre otros ficheros relacionados y entradas del manual.

Aunque en muchas versiones modernas de find el parámetro -print se asume por defecto, es conveniente acostumbrarse a usarlo por si debemos trabajar con versiones más antiguas en las que podríamos no obtener ninguna salida por pantalla.

El tiempo es oro

El comando find permite realizar búsquedas teniendo en cuenta las fechas de acceso o modificación de los ficheros, lo cual resulta muy útil para encontrar ficheros muy antiguos o los últimos en los que hemos realizado modificaciones, por ejemplo.

El siguiente comando busca los ficheros de nuestro directorio que se han modificado entre la fecha actual y dos días atrás utilizando la opción -mtime:

$ find /home/user -mtime -2 -print

Otras opciones disponibles son las siguientes:

-atime n Busca ficheros que tuvieron accesos hace n días.
-ctime n Busca ficheros cuyos atributos (por ejemplo, permisos) se modificaron hace n días.
-amin n Similar a -atime pero con accesos de hace n minutos.
-cmin n Similar a -ctime pero con modificaciones de hace n minutos.

El tamaño importa y el tipo también.

En la actualidad, es muy fácil llenar el disco duro instalando aplicaciones que ocupan grandes cantidades de espacio o bajando de Internet ficheros multimedia de tamaño elevado, por ejemplo. Por ello puede resultar útil poder encontrar ficheros que ocupan un cierto tamaño en el disco. La opción -size del comando find permite realizar una búsqueda de este tipo. Tras dicha opción, debemos especificar el tamaño, por defecto en bloques de 512 bytes (0.5Kb), añadiendo una k, en Kbytes o añadiendo una M en Mbytes. Asimismo podemos indicar que queremos encontrar los ficheros con tamaño igual o mayor al indicado añadiendo un `+’. Por ejemplo, el comando siguiente busca los ficheros mayores de 500 Kb en el directorio /usr/bin:

$ find /usr/bin -size +500k -print

Por otro lado, hasta ahora hemos dejado que find encuentre todo tipo de ficheros, incluyendo por ejemplo directorios. Pero es posible especificar con más detalle el tipo que queremos buscar con la opción –type, seguida de una letra, como vemos en el siguiente ejemplo en que restringe una búsqueda anterior únicamente a ficheros normales usando la letra ‘f’:

$ find /home/user -mtime -2 -type f -print

Otras opciones serían ‘d’ para directorios o ‘l’ para enlaces.

La hora de la ejecución

Ya hemos visto la gran flexibilidad que proporciona find a la hora de establecer criterios de búsqueda. Seguidamente, veremos cómo resulta una potente herramienta gracias a la posibilidad de ejecutar comandos sobre los resultados de la búsqueda.

Imaginemos que queremos realizar una copia de todos los ficheros de nuestro directorio de trabajo modificados como mucho hace dos días a un directorio de otro usuario llamado prueba. En el ejemplo anterior hemos visto que para encontrarlos podemos utilizar las opciones -mtime y -type del comando find. Pero ¿cómo podemos especificar que queremos realizar una acción de copia sobre ellos? La solución consiste en utilizar la opción -exec seguida del comando a ejecutar. En este caso el comando es cp y necesita saber el fichero a copiar y el destino. Este último es el directorio /home/prueba, pero no hay un sólo fichero a copiar sino una lista de la cual no sabemos los nombres hasta ejecutar el comando. Para solucionar este último problema, podemos utilizar los símbolos ‘{}’, que representan cada uno de los resultados proporcionados por find. Así, si escribimos ‘cp {} /home/prueba‘ significa ‘copia cada fichero resultante al directorio /home/prueba‘. Veamos la solución final:

$ find /home/user -mtime -2 -type f -exec cp {} /home/prueba \;

Las posibilidades de uso de esta opción son muy amplias siendo especialmente útil para automatizar tareas que se deben realizar sobre grupos de ficheros que cumplan ciertas características.

Prueba a utilizar la opción -exec con el comando rm para borrar los ficheros que has incluido en el directorio creado anteriormente. Ten cuidado, ya que puedes perder ficheros accidentalmente.