En este momento estás viendo La orden find

La orden find

La orden find

La orden «find» es una potente y práctica herramienta para buscar, recursivamente, en el árbol de directorios, ficheros que cumplan los criterios especificados en la línea de comandos. La búsqueda puede realizarse a través de todos los subárboles del directorio raíz, o de los directorios que indiquemos específicamente. También nos permitirá realizar operaciones sobre el resultado de la búsqueda.

Sumario

  • Uso básico de la orden «find»
  • Ampliación del comando «find»
  • Opciones del comando
  • Ejemplos de búsquedas
  • Búsquedas complejas
find orden para búsqueda de ficheros y directorios

Uso básico de la orden «find»

En su uso más básico, su sintaxis es

find [ruta_al_directorio] [expresiones]

ruta_al_directorio — indica los lugares de la jerarquía del árbol de directorios, desde los que se comienza la búsqueda recursiva, en orden descendente desde el directorio indicado, incluyendo los subdirectorios que contenga.

expresiones — especifica (mediante operadores), los criterios de selección para los ficheros que quieras localizar, y la acción que «find» debe tomar sobre ellos. Por ejemplo

find . -name "fich*" -print

busca recursivamente, a partir del directorio actual, todos los ficheros que empiecen por «fich» y muestra sus nombres en pantalla. El punto significa el directorio actual.

Ejemplos

Para buscar en nuestro directorio $HOME todos aquellos ficheros que tengan el uid 0, es decir, que pertenezcan al usuario root.

find ~ -type f -uid 0
Ficheros del usuario root

Si queremos buscar en nuestro directorio $HOME todos aquellos ficheros que tengan el uid 0 (que pertenezcan al usuario root), y listarlos podemos hacer uso de «-exec» con el comando «ls -l». La acción a realizar se especifica mediante el argumento de la opción «-exec». Y si además quieres guardar la salida estándar en un fichero…

find ~ -uid 0 -type f -exec ls -l {} \; >resultado
Guarda el resultado en el fichero «resultado»

Otra alternativa es sustituir «~» por la variable $HOME. Con la orden

find $HOME -atime +7 -exec rm {} \;

busca aquellos ficheros localizados por debajo del directorio HOME que no han sido accedidos en los últimos siete días y los borra. En este caso, el criterio de búsqueda viene dado por la opción «-atime», que luego veremos. Lo ejecuto con «ls», ya que no quiero borrar nada.

find $HOME -atime +7 -exec ls -l {} \;
Búsqueda con «atime»

Los símbolos {} se sustituyen por el «path» completo de cada fichero encontrado. Es necesario terminar la orden «exec» con «\;».

Para buscar en varios directorios, con la orden siguiente buscará en /dir1 y /dir2/dir3

find /dir1 /dir2/dir3 -exec grep "Weblinus$" {} \;

En mi caso ejecuto, para buscar todas aquellas líneas que acaben en Weblinus, dentro de los ficheros situados por debajo de los directorios ~/Find y ~/Busquedas/Weblinus.

find ~/Find ~/Busquedas/Weblinus -exec grep "Weblinus$" {} \;
Filtrado con «grep»

Ampliación del comando «find»

Este comando nos permite realizar búsquedas más refinadas de ficheros dentro de nuestro sistema. Su sintaxis básica es la siguiente, el nombre del fichero entre comillas,

find path -name "nombreFichero" 

Las búsquedas que se realizan con el comando «find» se hacen de forma recursiva. Por ejemplo para encontrar el fichero «resultado» dentro del directorio actual en el que nos encontramos, habría que ejecutar lo siguiente

find . -name "resultado"
Buscamos el fichero «resultado»

Por defecto, la búsqueda del fichero es «case-sensitive», lo que quiere decir que se buscará el nombre del fichero según se haya escrito, diferenciando entre mayúsculas y minúsculas en el nombre del fichero que se va a buscar. En el ejemplo anterior hemos buscado el fichero «resultado», pero si hubiese un fichero llamado «resultadO», no nos lo mostraría. Para hacer que busque todos los ficheros, sin tener en cuenta mayúsculas y minúsculas, tenemos que ejecutar el comando de la siguiente manera

find . -iname "resultadO"
Para que no distinga entre mayúsculas y minúsculas

Opciones del comando

El comando find tiene una gran cantidad de opciones, vamos a enumerar y a explicar las principales

  • -type: especifica que tipo de fichero se quiere buscar. Los tipos de fichero que se pueden indicar para buscar, son los siguientes
    • d – directorios
    • l – enlaces simbólicos
    • s – sockets
    • c – caracteres especiales
  • Otras opciones
    • -perm: se busca ficheros que posean los permisos que se indican. Si se pone delante de los permisos «-» se busca aquellos que no posean esos permisos.
    • -group: se buscan ficheros que sean miembro de determinado grupo.
    • -nouser: se buscan ficheros cuyo propietario sea el usuario indicado.
    • -nogroup: se buscan ficheros que sean miembro de determinado grupo.
    • -size: busca ficheros de un determinado tamaño.
    • -newer: busca ficheros que sean más nuevos que el fichero 1 pero más antiguos que el fichero 2.
    • -mtime (modify time): busca ficheros que han sido modificados antes de x días. Si pone el carácter «-« antes de los días, se buscan ficheros que han sido modificados en ese mismo día o antes. Si se pusiese «-mtime -5» se buscarían aquellos ficheros que han sido modificados hace 5 días. Si ponemos el carácter «+» se buscan ficheros que no han sido modificados en los días pasados como parámetros. Con «-atime» (access time), nos mostrará los ficheros accedidos desde una fecha especificada y con «-ctime» (change time) ,buscará los que han sido modificados en cuanto a permisos, propietario o grupo.

Hay muchas más opciones. Para consultarlas todas tienes el manual integrado del comando

man find
Manual integrado

Ejemplos de búsquedas

Buscar el fichero «buscado.txt» en el directorio actual

find . -name "buscado.txt"

Buscar ficheros cuyo nombre sea «buscado.txt» sin tener en cuentas mayúsculas ni minúsculas, como hemos visto,

find . -iname "Buscado.txt"
Búsqueda por nombre de fichero

Buscar ficheros cuya primera letra sea A,B o C en el directorio /etc

find /etc -name "[ABC]*"
Búsqueda de ficheros que empiezan por A, B o C

Buscar ficheros que terminen en «wd» en el directorio /etc, sin importar las mayúsculas y minúsculas y redirigir la salida al fichero find.log. En este caso necesitaremos escalar privilegios.

sudo find /etc -iname "*wd" > find.log
Salida redirigida a otro fichero

Realizar lo mismo anterior, pero mandando los mensajes de error al fichero «findErrors.log»

sudo find /etc -iname "*wd" 2>findError.log
Errores redirigidos al fichero «findError»

Para no ver los mensajes de error por pantalla, de la misma búsqueda,

sudo find /etc/ -iname "*wd" 2>/dev/null

Buscar en el directorio actual los directorios que contiene

find . -type d
Búsqueda de directorios

Buscar en el directorio actual los directorios que empiezan por D

find . -type d -name "D*"
Búsqueda de directorios que empiezan con D

Búsquedas complejas

Hasta ahora las búsquedas que hemos visto son búsquedas sencillas, veamos unos ejemplos de búsquedas más complejas ayudándonos de tuberías o pipes.

Vamos a buscar, en el directorio /etc, el fichero «passwd» y localizar, dentro de este, si hay algún usuario llamado root

find /etc -name "passwd" | xargs grep "root"

Podemos hacer la misma búsqueda evitando que se muestren mensajes de error por pantalla

find /etc -name "passwd" 2>/dev/null | xargs grep "root"
Busqueda y filtrado con grep

Búsquedas con «xarg»

El comando xargs permite la ejecución de un comando, tomando como parámetro de entrada, en la entrada estandar. Para el ejemplo anterior, localizaría el fichero «passwd», dentro del directorio /etc, y en el caso de encontrar alguna coincidencia, se ejecutaría el comando grep, que buscaría la cadena de texto «root». En el caso de que se produzcan errores en la búsqueda del fichero «passwd», debido por ejemplo a la falta de permisos para acceder a un determinado directorio, estos se mandarán a /dev/null y no veríamos dichos mensajes por la pantalla.

Para hacer la misma búsqueda que en el caso anterior, pero que esta vez que se muestren todos los usuarios del fichero passwd, excepto «root»

find /etc -name "passwd" 2>/dev/null | xargs grep -v "root"
Búsqueda compleja

Y si quisiéramos borrar los ficheros que empiecen por «A» en el directorio actual y hacia abajo recursivamente, ejecutaríamos

find . -type f -iname "A*" | xargs rm

Si además queremos que nos pida confirmación antes de borrar,

find . -type f -name "A*" -exec rm -i {} \;

La opción -exec permite realizar lo mismo que con la opción xargs, pero sin usar una tubería o pipe. La sintaxis de -exec es la siguiente

find path -name nombreFichero -exec comandoAEjecutar {} \;

Búsquedas con «exec»

Cuando se usa la opción -exec, el comando find aplica a todos los resultados obtenidos, la orden especificada después, uno por uno. En algunos sistemas existe un límite en la longitud de la cadena que se le puede pasar a exec, por lo que, al rato de estar ejecutándose esta búsqueda, terminará con error. Para estos casos es mejor utilizar xargs.

Vemos esta opción. Por ejemplo, para buscar ficheros dentro del nuestro directorio de trabajo que contengan sh en su nombre y ver su información.

find $HOME -name "*sh*" | xargs ls -l
Búsqueda de ficheros que contienen los caracteres s y h, y los lista

Si lo que queremos es buscar aquellos ficheros que han sido modificados en los últimos 2 días

find . -type f -mtime -2
Búsqueda de ficheros modificados en los últimos 2 días

Búsqueda de varios ficheros

Si se quiere buscar más de un fichero con el comando find se hace usando el parámetro «-o«. Lo que se consigue con este parámetro es hacer búsquedas en las que se cumpla, o una condición u otra. Por ejemplo para buscar todos los ficheros con extensión «xml» y «xsl» del directorio actual se haría de la siguiente forma

find . -name "*.xml" -o -name "*.xsl"

Para buscar en $HOME todos los ficheros que pertenezcan a mi usuario y que tengan permiso de lectura y ejecución para el grupo y otros, y listarlos con -exec.

find ~ -perm 755 -type f -user $LOGNAME -exec ls -l {} \;
Búsqueda por permisos y propiedad

Para que aparezcan los directorios sería

find ~ -perm 777 -type d -user $LOGNAME -exec ls -ld {} \;
Muestra los directorios

La salida es enorme…

Si queremos buscar en nuestra $HOME aquellos ficheros que hayan sido modificados en los últimos 2 días y hacer un paquete «tar» con ellos.

tar cvzf ultimos.tgz $(find ~ -mtime -2)

Veamos un último ejemplo. Para buscar aquellos ficheros en nuestra $HOME, cuyo tamaño supere los 100 Mb y guardar una lista de su tamaño y nombre ordenada por tamaño en un fichero.

find $HOME -type f -size +100M -exec ls -l {} \; | tr -s " " " " | cut -f5,9 -d" " | sort -nr >lista_100M
Búsqueda de ficheros de más de 100 Mb

Si tienes algún comentario que hacer sobre este artículo, al pie del post tienes un formulario para hacerlo.

Si quieres contactar conmigo por cualquier otro asunto relacionado con el sitio, en la página de contacto, tienes un formulario más adecuado.

Y para suscribirte y recibir las novedades publicadas, tienes un enlace en pie de la página o desde aquí mismo.

Esta entrada tiene 2 comentarios

  1. Josevi

    Interesante artículo. Hoy en día las búsquedas de «andar por casa» se hacen en entorno gráfico, pero para una búsqueda discriminada es muy útil este comando: permite muchas opciones y al final rentabiliza mucho el tiempo.

Deja una respuesta

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