En sistemas operativos tipo Unix , es una utilidad de línea de comandos que localiza archivos según algunos criterios especificados por el usuario e imprime la ruta de cada objeto coincidente o, si se solicita otra acción, realiza esa acción en cada objeto coincidente. find
Inicia una búsqueda desde una ubicación de inicio deseada y luego recorre recursivamente los nodos (directorios) de una estructura jerárquica (normalmente un árbol ). find puede recorrer y buscar en diferentes sistemas de archivos de particiones que pertenecen a uno o más dispositivos de almacenamiento montados bajo el directorio de inicio. [1]
Los posibles criterios de búsqueda incluyen un patrón para comparar con el nombre del archivo o un rango de tiempo para comparar con la hora de modificación o la hora de acceso al archivo. De manera predeterminada, devuelve una lista de todos los archivos que se encuentran debajo del directorio de trabajofind
actual , aunque los usuarios pueden limitar la búsqueda a cualquier número máximo deseado de niveles debajo del directorio de inicio.
Los programas relacionados locate
utilizan una base de datos de archivos indexados obtenidos a través de find
(actualizados a intervalos regulares, generalmente por cron
trabajo) para proporcionar un método más rápido de búsqueda de archivos por nombre en todo el sistema de archivos.
find
apareció en la versión 5 de Unix como parte del proyecto Programmer's Workbench , y fue escrito por Dick Haight junto con cpio , [2] que fueron diseñados para usarse juntos. [3]
La implementación de GNU find
fue escrita originalmente por Eric Decker y luego fue mejorada por David MacKenzie, Jay Plett y Tim Wood. [4]
El comando find también ha sido portado al sistema operativo IBM i . [5]
$ find [ -H | -L ] ruta... [ expresión_de_operando... ]
Las dos opciones controlan cómo el find
comando debe tratar los enlaces simbólicos. El comportamiento predeterminado es nunca seguir enlaces simbólicos. La -L
bandera hará que el find
comando siga enlaces simbólicos. La -H
bandera solo seguirá enlaces simbólicos mientras procesa los argumentos de la línea de comandos. Estas banderas se especifican en el estándar POSIX para find
. [6] Una extensión común es la -P
bandera para deshabilitar explícitamente el seguimiento de enlaces simbólicos. [7] [8]
Al menos una ruta debe preceder a la expresión. find
es capaz de interpretar comodines internamente y los comandos deben estar entre comillas cuidadosamente para controlar el uso excesivo del shell .
Los elementos de expresión están separados por el límite del argumento de la línea de comandos , que normalmente se representa como un espacio en blanco en la sintaxis del shell. Se evalúan de izquierda a derecha. Pueden contener elementos lógicos como AND ( -and
o -a
) y OR ( -or
o -o
), así como predicados (filtros y acciones).
GNU find
tiene una gran cantidad de características adicionales no especificadas por POSIX.
Las primarias comúnmente utilizadas incluyen:
-name pattern
:comprueba si el nombre del archivo coincide con el patrón shell-glob indicado.-type type
: comprueba si el archivo es de un tipo determinado. Los tipos de archivos Unix aceptados incluyen:b
: dispositivo de bloque (almacenado en búfer) ;c
: dispositivo de caracteres (sin búfer) ;d
: directorio ;f
: archivo regular ;l
: enlace simbólico ;p
: tubería con nombre ;s
: zócalo ;D
: puerta .-print
: siempre devuelve verdadero; imprime el nombre del archivo actual más una nueva línea en la salida estándar .-print0
: siempre devuelve verdadero; imprime el nombre del archivo actual más un carácter nulo en la salida estándar . No es requerido por POSIX.-exec program [arguments...] ;
: ejecuta el programa con los argumentos dados y devuelve verdadero si su estado de salida era 0, falso en caso contrario. Si el programa o un argumento es {} , se reemplazará por la ruta actual (si el programa es {} , find
intentará ejecutar la ruta actual como un ejecutable). POSIX no especifica qué debería suceder si se especifican varios {} . La mayoría de las implementaciones reemplazarán todos los {} con la ruta actual, pero ese no es un comportamiento estándar.-exec program [arguments...] {} +
: siempre devuelve verdadero; ejecuta el programa con los argumentos dados, seguido de tantas rutas como sea posible (se ejecutarán varios comandos si se excede el tamaño máximo de la línea de comandos, como para xargs ). [6]-ok program [arguments...] ;
:para cada ruta, solicita confirmación al usuario; si el usuario confirma (normalmente ingresando y o yes ), se comporta como , de lo contrario, el comando no se ejecuta para la ruta actual y se devuelve false .-exec program [arguments...] ;
-maxdepth
: Se puede utilizar para limitar la profundidad de búsqueda en el directorio. Por ejemplo, -maxdepth 1
limita la búsqueda al directorio actual.Si la expresión no utiliza ninguno de -print0
los valores -print
, -exec
, o -ok
, busque valores predeterminados para ejecutarse -print
si las condiciones se prueban como verdaderas.
Se pueden utilizar operadores para mejorar las expresiones del comando find. Los operadores se enumeran en orden de precedencia decreciente:
( expr )
: fuerzas de precedencia;! expr
: verdadero si expr es falso;expr1 expr2
(o expr1 -a expr2
: AND. expr2
no se evalúa si expr1
es falso;expr1 -o expr2
:OR. expr2 no se evalúa si expr1
es verdadero.$ find . -name 'archivoA_*' -o -name 'archivoB_*'
Este comando busca en el árbol de directorios de trabajo actual archivos cuyos nombres comiencen con fileA_
o fileB_
. Ponemos el fileA_*
para que el shell no lo expanda.
$ find . -nombre 'foo.cpp' '!' -ruta '.svn'
Este comando busca en el árbol de directorios de trabajo actual, excepto en el árbol de subdirectorios ".svn", archivos cuyo nombre sea "foo.cpp". Lo ponemos entre comillas !
para que el shell no lo interprete como el carácter de sustitución del historial.
Los sistemas de archivos del mundo real a menudo contienen estructuras en bucle creadas mediante el uso de enlaces duros o blandos . El estándar POSIX requiere que
La
find
utilidad detectará bucles infinitos, es decir, el ingreso a un directorio visitado previamente que sea un antecesor del último archivo encontrado. Cuando detecte un bucle infinito,find
escribirá un mensaje de diagnóstico en el error estándar y recuperará su posición en la jerarquía o finalizará.
$ find . -name 'mi*'
Esta función busca en el árbol de directorios de trabajo actual los archivos cuyos nombres comiencen con my . Las comillas simples evitan la expansión del shell ; sin ellas, el shell reemplazaría my* con la lista de archivos cuyos nombres comiencen con my en el directorio de trabajo actual. En versiones más nuevas del programa, se puede omitir el directorio, y esto implicará el directorio de trabajo actual.
$ find . -name 'mi*' -type f
Esto limita los resultados de la búsqueda anterior solo a archivos regulares, excluyendo así directorios, archivos especiales, enlaces simbólicos, etc. my* está entre comillas simples (apóstrofos) ya que de lo contrario el shell lo reemplazaría con la lista de archivos en el directorio de trabajo actual comenzando con my …
Los ejemplos anteriores crearon listas de resultados porque, de manera predeterminada, find
ejecuta la -print
acción. (Tenga en cuenta que las primeras versiones del find
comando no tenían ninguna acción predeterminada; por lo tanto, la lista de archivos resultante se descartaba, para desconcierto de los usuarios).
$ find . -name 'mi*' -type f -ls
Esto imprime información de archivo extendida.
$ find / -name miarchivo -type f -print
Esta función busca en cada directorio un archivo normal cuyo nombre sea myfile y lo imprime en la pantalla. Generalmente no es una buena idea buscar archivos de esta manera. Esto puede llevar una cantidad considerable de tiempo, por lo que es mejor especificar el directorio con mayor precisión. Algunos sistemas operativos pueden montar sistemas de archivos dinámicos que no son compatibles con find
. Es posible que los nombres de archivos más complejos que incluyan caracteres especiales del shell deban incluirse entre comillas simples.
$ find / -path ruta_excluida -prune -o -type f -name miarchivo -print
Esto busca en cada directorio excepto el árbol de subdirectorios excluido_ruta (ruta completa incluyendo el / inicial) que es podado por la -prune
acción, un archivo regular cuyo nombre es miarchivo .
$ find /home/weedly -name miarchivo -type f -print
Esta opción busca en el árbol de directorios /home/weedly archivos regulares llamados myfile . Siempre debe especificar el directorio al nivel más profundo que pueda recordar.
$ find local /tmp -name midir -type d -print
Esto busca en el árbol de subdirectorios local del directorio de trabajo actual y en el árbol de directorios /tmp los directorios llamados mydir .
Si está haciendo esto como un usuario distinto de root, es posible que desee ignorar los errores de permiso denegado (y cualquier otro). Dado que los errores se imprimen en stderr , se pueden suprimir redirigiendo la salida a /dev/null. El siguiente ejemplo muestra cómo hacer esto en el shell bash:
$ find / -name miarchivo -type f -print 2 > /dev/null
Si es un usuario de csh o tcsh , no puede redirigir stderr sin redirigir también stdoutfind
. Puede usar sh para ejecutar el comando para solucionar este problema:
$ sh -c "find / -name miarchivo -type f -print 2> /dev/null"
Un método alternativo al utilizar csh o tcsh es canalizar la salida de stdout y stderr a un comando grep . Este ejemplo muestra cómo suprimir líneas que contienen errores de permiso denegado.
$ find . -name myfile |& grep -v 'Permiso denegado'
$ buscar . \( -nombre '*jsp' -o -nombre '*java' \) -tipo f -ls
El -ls
operador imprime información extendida y el ejemplo encuentra cualquier archivo regular cuyo nombre termine con 'jsp' o 'java'. Tenga en cuenta que los paréntesis son obligatorios. En muchos shells, los paréntesis deben escaparse con una barra invertida ( \(
y \)
) para evitar que se interpreten como caracteres especiales del shell. El -ls
operador no está disponible en todas las versiones de find
.
$ buscar /var/ftp/mp3 -name '*.mp3' -type f -exec chmod 644 {} \;
Este comando cambia los permisos de todos los archivos regulares cuyos nombres terminan con .mp3 en el árbol de directorios /var/ftp/mp3 . La acción se lleva a cabo especificando la declaración en el comando. Para cada archivo regular cuyo nombre termina en , el comando se ejecuta reemplazando con el nombre del archivo. El punto y coma (con barra invertida para evitar que el shell lo interprete como un separador de comandos) indica el final del comando. El permiso , que generalmente se muestra como , le da al propietario del archivo permiso total para leer y escribir el archivo, mientras que otros usuarios tienen acceso de solo lectura. En algunos shells, el debe estar entre comillas. El " " final se suele citar con un " " inicial, pero también se puede encerrar entre comillas simples.-exec chmod 644 {} \;
.mp3
chmod 644 {}
{}
644
rw-r--r--
{}
;
\
Tenga en cuenta que el comando en sí no debe estar entre comillas; de lo contrario, obtendrá mensajes de error como
find: echo "mv ./3bfn rel071204": No existe el archivo o directorio
lo que significa que find
está intentando ejecutar un archivo llamado ' ' y falla.echo "mv ./3bfn rel071204"
Si va a ejecutar muchos resultados, es más eficiente utilizar una variante del exec primary que recopila nombres de archivos hasta ARG_MAX y luego ejecuta COMMAND con una lista de nombres de archivos.
$ find . -exec COMANDO {} +
Esto garantizará que los nombres de archivos con espacios en blanco se pasen al ejecutable COMMAND
sin que el shell los divida.
La -delete
acción es una extensión de GNU y su uso activa -depth
. Por lo tanto, si está probando un comando find con -print
en lugar de -delete
para averiguar qué sucederá antes de ejecutarlo, debe usar -depth -print
.
Eliminar archivos vacíos e imprimir los nombres (tenga en cuenta que -empty
es una extensión exclusiva del proveedor de GNU find
que puede no estar disponible en todas find
las implementaciones):
$ buscar . -vacío -borrar -imprimir
Eliminar archivos regulares vacíos:
$ buscar . -tipo f -vacío -eliminar
Eliminar directorios vacíos:
$ buscar . -tipo d -vacío -eliminar
Eliminar archivos vacíos llamados 'bad':
$ find . -name incorrecto -vacío -eliminar
Advertencia. — La -delete
acción debe utilizarse con condiciones como -empty
o -name
:
$ find . -delete # esto elimina todo en .
Este comando buscará una cadena en todos los archivos del árbol de directorios /tmp:
$ find /tmp -type f -exec grep 'cadena de búsqueda' /dev/null '{}' \+
El /dev/null
argumento se utiliza para mostrar el nombre del archivo antes del texto encontrado. Sin él, solo se imprime el texto encontrado. (Alternativamente, algunas versiones de grep admiten un indicador -H que fuerza la impresión del nombre del archivo). GNU se puede utilizar por sí solo para realizar esta tarea:grep
$ grep -r 'cadena de búsqueda' /tmp
Ejemplo de búsqueda de "LOG" en el árbol de directorios de inicio de jsmith:
$ find ~jsmith -exec grep LOG '{}' /dev/null \; -print /home/jsmith/scripts/errpt.sh:cp $LOG $FIXEDLOGNAME /home/jsmith/scripts/errpt.sh:cat $LOG /home/jsmith/scripts/title:USUARIO=$LOGNAME
Ejemplo de búsqueda de la cadena "ERROR" en todos los archivos XML del árbol de directorios de trabajo actual:
$ find . -name "*.xml" -exec grep "ERROR" /dev/null '{}' \+
Las comillas dobles (" ") que rodean la cadena de búsqueda y las comillas simples (' ') que rodean las llaves son opcionales en este ejemplo, pero son necesarias para permitir espacios y otros caracteres especiales en la cadena. Tenga en cuenta que con texto más complejo (especialmente en los shells más populares que descienden de `sh` y `csh`) las comillas simples suelen ser la opción más sencilla, ya que las comillas dobles no evitan todas las interpretaciones especiales . Entrecomillar nombres de archivos que tienen contracciones en inglés demuestra cómo esto puede volverse bastante complicado, ya que una cadena con un apóstrofo es más fácil de proteger con comillas dobles:
$ find . -name "archivo-que-contiene-no-puede" -exec grep "no puede" '{}' \; -print
$ find . -user <id de usuario>
Tenga en cuenta que esto -iname
no está en el estándar y es posible que no sea compatible con todas las implementaciones.
$ find . -iname 'MiArchivo*'
Si -iname
su sistema no admite el conmutador, es posible que existan técnicas alternativas como:
$ buscar . -nombre '[mM][yY][fF][iI][lL][eE]*'
Búsqueda de archivos cuyo tamaño esté entre 100 kilobytes y 500 kilobytes:
$ buscar . -tamaño +100k -a -tamaño -500k
Buscando archivos vacíos:
$ buscar . -tamaño 0k
Buscando archivos no vacíos:
$ buscar . ! -tamaño 0k
$ find /usr/src ! \( -nombre '*,v' -o -nombre '.*,v' \) '{}' \; -imprimir
Este comando buscará en el árbol de directorios /usr/src. Se excluyen todos los archivos con el formato '*,v' y '.*,v' . Los argumentos importantes que se deben tener en cuenta se encuentran en la información sobre herramientas que se muestra al pasar el mouse por encima.
para el archivo en $( find /opt \( -name error_log -o -name 'access_log' -o -name 'ssl_engine_log' -o -name 'rewrite_log' -o -name 'catalina.out' \) -size +300000k -a -size -5000000k ) ; hacer cat /dev/null > $file hecho
Las unidades deben ser una de [bckw] , 'b' significa bloques de 512 bytes, 'c' significa byte, 'k' significa kilobytes y 'w' significa palabras de 2 bytes. El tamaño no cuenta los bloques indirectos, pero sí los bloques en archivos dispersos que no están realmente asignados.
Los rangos de fechas se pueden utilizar, por ejemplo, para enumerar archivos modificados desde una copia de seguridad.
-mtime
:hora de modificación-ctime
:tiempo de cambio de inodo-atime
:tiempo de accesoArchivos modificados hace un número relativo de días:
-daystart
para medir el tiempo desde el comienzo del día (0 en punto) en lugar de las últimas 24 horas.Ejemplo para buscar todos los archivos de texto en la carpeta de documentos modificados desde hace una semana (es decir, 7 días):
$ find ~/Documentos/ -iname "*.txt" -mtime -7
Archivos modificados antes o después de una fecha y hora absolutas:
-newermt YYYY-MM-DD
:Última modificación después de la fecha-not -newermt YYYY-MM-DD
:Última modificación antes de la fechaEjemplo para encontrar todos los archivos de texto editados por última vez en febrero de 2017:
$ find ~ / Documentos/ -iname "*.txt " -newermt 2017-02-01 -not -newermt 2017-03-01
-newer [file]
:Archivo modificado más recientemente que el especificado.-cnewer
:Lo mismo ocurre con el tiempo de cambio de inodo.-anewer
:Lo mismo ocurre con el tiempo de acceso.-not
para resultados inversos o rango.Enumere todos los archivos de texto editados más recientemente que "document.txt":
$ find ~/Documentos/ -iname "*.txt" -newer documento.txt
locate
es una herramienta de búsqueda de Unix que busca en una base de datos de archivos predefinida en lugar de en árboles de directorios de un sistema de archivos. Es más rápida que .NET, find
pero menos precisa porque la base de datos puede no estar actualizada.grep
es una utilidad de línea de comandos para buscar conjuntos de datos de texto simple en busca de líneas que coincidan con una expresión regular y, de forma predeterminada, informar las líneas coincidentes en la salida estándar .tree
es una utilidad de línea de comandos que enumera de forma recursiva los archivos que se encuentran en un árbol de directorios, sangrando los nombres de archivo según su posición en la jerarquía de archivos.find
y xargs
.find
.dir
tiene la opción /s que busca recursivamente archivos o directorios.find
: una walk
que solo recorre el árbol e imprime los nombres y una sor
que solo filtra (como grep) evaluando expresiones en forma de un script de shell. Se pueden usar filtros arbitrarios a través de tuberías. Los comandos no son parte de Plan 9 de User Space , por lo que Benjamin Barenblat de Google tiene una versión portada a sistemas POSIX disponible a través de GitHub. [9]fd
es una alternativa sencilla a find
la programación escrita en el lenguaje Rust . [10]find
find
find