stringtranslate.com

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 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:

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:

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

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

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:

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      

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

$ find  ~/Documentos/  -iname "*.txt" -newer documento.txt   

Utilidades relacionadas

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 .

Enlaces externos