Articulo de referencia

encontrar (Unix)

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 obje...

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 locateutilizan una base de datos de archivos indexados obtenidos a través de find(actualizados a intervalos regulares, generalmente por crontrabajo) para proporcionar un método más rápido de búsqueda de archivos por nombre en todo el sistema de archivos.

Historia

findapareció 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]

Encontrar sintaxis

$ find [ -H | -L ] ruta... [ expresión_de_operando... ]   

Las dos opciones controlan cómo el findcomando debe tratar los enlaces simbólicos. El comportamiento predeterminado es nunca seguir enlaces simbólicos. La -Lbandera hará que el findcomando siga enlaces simbólicos. La -Hbandera 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 -Pbandera para deshabilitar explícitamente el seguimiento de enlaces simbólicos. [7] [8]

Al menos una ruta debe preceder a la expresión. findes capaz de interpretar comodines internamente y los comandos deben estar entre comillas cuidadosamente para controlar el uso global 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 ( -ando -a) y OR ( -oro -o), así como predicados (filtros y acciones).

GNU findtiene una gran cantidad de características adicionales no especificadas por POSIX.

Predicados

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:
  • -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 {} , findintentará 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 1limita la búsqueda al directorio actual.

Si la expresión no utiliza ninguno de -print0los valores -print, -exec, o -ok, busque valores predeterminados para ejecutarse -printsi las condiciones se prueban como verdaderas.

Operadores

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. expr2no se evalúa si expr1es falso;
  • expr1 -o expr2:OR. expr2 no se evalúa si expr1es 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.

Protección POSIX contra salida infinita

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 findutilidad detectará bucles infinitos, es decir, el ingreso a un directorio visitado anteriormente que es un antecesor del último archivo encontrado. Cuando detecte un bucle infinito, findescribirá un mensaje de diagnóstico en el error estándar y recuperará su posición en la jerarquía o finalizará.

Ejemplos

Desde el directorio de trabajo actual

$ 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.

Solo archivos normales

$ 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

Comandos

Los ejemplos anteriores crearon listas de resultados porque, de manera predeterminada, findejecuta la -printacción. (Tenga en cuenta que las primeras versiones del findcomando 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.

Buscar en todos los directorios

$ 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.

Buscar en todos los subdirectorios excepto uno

$ 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 -pruneacción, un archivo regular cuyo nombre es miarchivo .

Especificar un directorio

$ 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.

Busque en varios directorios

$ 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 .

Ignorar errores

Si está haciendo esto como un usuario que no sea 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'    

Busque cualquiera de los archivos con nombres diferentes

$ buscar  . \( -nombre '*jsp' -o -nombre '*java' \) -tipo f -ls
          

El -lsoperador 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 -lsoperador no está disponible en todas las versiones de find.

Ejecutar una acción

$ 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 {} \;.mp3chmod 644 {}{}644rw-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 findestá 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 COMMANDsin que el shell los divida.

Eliminar archivos y directorios

La -deleteacción es una extensión de GNU y su uso activa -depth. Por lo tanto, si está probando un comando find con -printen lugar de -deletepara averiguar qué sucederá antes de ejecutarlo, debe usar -depth -print.

Eliminar archivos vacíos e imprimir los nombres (tenga en cuenta que -emptyes una extensión exclusiva del proveedor de GNU findque puede no estar disponible en todas findlas 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 -deleteacción debe utilizarse con condiciones como -emptyo -name:

$ find  .  -delete # esto elimina todo en . 

Buscar una cadena

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/nullargumento 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
       

Buscar todos los archivos propiedad de un usuario

$ find  .  -user  <id de usuario>

Buscar en modo que no distinga entre mayúsculas y minúsculas

Tenga en cuenta que esto -inameno está en el estándar y es posible que no sea compatible con todas las implementaciones.

$ find  .  -iname 'MiArchivo*' 

Si -inamesu sistema no admite el conmutador, es posible que existan técnicas alternativas como:

$ buscar  .  -nombre '[mM][yY][fF][iI][lL][eE]*' 

Buscar archivos por tamaño

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

Buscar archivos por nombre y tamaño

$ 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.

Búsqueda de archivos por tiempo

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 acceso

Archivos modificados hace un número relativo de días:

  • +[número] = Al menos hace tantos días.
  • -[número] = Menos que hace tantos días.
  • [número] = Hace exactamente esta cantidad de días.
  • Opcionalmente, agregue -daystartpara 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 fecha

Ejemplo 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.
    • También se puede anteponer con -notpara resultados inversos o rango.

Enumere todos los archivos de texto editados más recientemente que "document.txt":

$ find  ~/Documentos/  -iname "*.txt" -newer documento.txt
    
  • locatees 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, findpero menos precisa porque la base de datos puede no estar actualizada.
  • grepes 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 .
  • treees 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.
  • GNU Find Utilities (también conocido como findutils) es un paquete GNU que contiene implementaciones de las herramientas findy xargs.
  • BusyBox es una utilidad que proporciona varias herramientas de Unix simplificadas en un único archivo ejecutable, pensada para sistemas operativos integrados con recursos muy limitados. También proporciona una versión de find.
  • dirtiene la opción /s que busca archivos o directorios de forma recursiva.
  • Plan 9 de Bell Labs utiliza dos utilidades para reemplazar find: una walkque solo recorre el árbol e imprime los nombres y una sorque 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]
  • fdes una alternativa sencilla a findla programación escrita en el lenguaje Rust . [10]

Véase también

Referencias

  1. ^ "find(1) - Página del manual de Linux". man7.org . Consultado el 19 de noviembre de 2019 .
  2. ^ McIlroy, MD (1987). Un lector de Unix para investigación: extractos anotados del Manual del programador, 1971–1986 (PDF) (Informe técnico). CSTR. Bell Labs. 139.
  3. ^ "libarchive/libarchive". GitHub . Consultado el 4 de octubre de 2015 .
  4. ^ Encontrar archivos
  5. ^ "Programación Qshell para IBM System i versión 7.2" (PDF) . IBM . Consultado el 5 de septiembre de 2020 .
  6. ^ ab find: buscar archivos – Referencia de shell y utilidades, La especificación única de UNIX , versión 4 de The Open Group
  7. ^ find(1)  –  Manual de comandos generales de FreeBSD
  8. ^ find(1)  –  Manual de usuario de Linux – Comandos de usuario
  9. ^ "google/walk: utilidades de estilo Plan 9 para reemplazar find(1)". GitHub . Consultado el 30 de marzo de 2020 .
  10. ^ Peter, David (30 de marzo de 2020). «sharkdp/fd: una alternativa sencilla, rápida y fácil de usar a 'find'». GitHub .
  • Página web oficial de GNU find
  • Comando find – 25 ejemplos prácticos
Retrieved from "https://en.wikipedia.org/w/index.php?title=Find_(Unix)&oldid=1247077942"