¿Cómo encontrar un archivo en el sistema de archivos desde la línea de comandos?

10

Me gustaría encontrar dónde está un archivo (con un nombre de archivo parcialmente conocido) en el sistema de archivos. Me gustaría saber cómo hacer esto desde la línea de comandos, en lugar de usar una utilidad GUI.

En Windows, ejecutaría lo siguiente:

cd /d C:\
dir *filename* /s

¿Cuál es el equivalente de Linux?

Iszi
fuente
Bueno, obviamente hay más de una forma de desollar a este gato. ¿Todavía tengo curiosidad por saber si hay una manera de hacerlo ls?
Iszi

Respuestas:

13
locate filename
find -name '*filename*'
echo **/*filename*
ls -ld **/*filename*

(Siga leyendo para conocer los términos y condiciones principales. Lea el manual para la letra pequeña).

Listar el contenido de un directorio es una especie de característica secundaria de ls. El trabajo principal de ls, el que ocupa la mayor parte de su complejidad, es ajustar su pantalla. (Consulte el manual y compare la cantidad de opciones relacionadas con la elección de los archivos que se mostrarán frente a la cantidad de opciones que controlan qué información mostrar acerca de cada archivo y cómo se formatea la pantalla. Esto es cierto tanto para GNU como para usted). lo encontraré en Linux y en otros sistemas con menos opciones, desde los primeros días).

El modo predeterminado de lses que cuando le pasa un directorio, enumera los archivos en ese directorio. Si le pasa cualquier otro tipo de archivo (archivo normal, enlace simbólico, etc.), solo se muestra ese archivo. (Esto se aplica a cada argumento por separado). La opción -dle dice que lsnunca descienda a un directorio.

lstiene una opción -Rque le dice que enumere directorios de forma recursiva. Pero tiene una aplicabilidad limitada y no permite mucho filtrado en la salida.

La primera herramienta para realizar la coincidencia de patrones es el propio shell. No necesita ningún otro comando: simplemente escriba sus comodines y estará listo. Esto se conoce como globbing .

echo *filename*

Tradicionalmente, los comodines se limitaban al directorio actual (o al directorio indicado:) echo /some/where/*filename*. A *coincide con cualquier nombre de archivo, o cualquier parte del nombre de archivo, pero *.txtno coincide foo/bar.txt. Los shells modernos han agregado el patrón **/que significa "en este directorio, o en cualquier directorio debajo de él (recursivamente)". Con bash, por razones de compatibilidad histórica, esta característica debe habilitarse explícitamente con shopt -s globstar(puede poner esta línea en su ~/.bashrc).

echo **/*filename*

El echocomando solo repite la lista de nombres de archivo generados por el shell. Como excepción, si no hay ningún nombre de archivo coincidente, el patrón comodín no se modifica en bash (a menos que establezca shopt -s nullglob, en cuyo caso el patrón se expande a una lista vacía), y zsh señala un error (a menos que establezca setopt nullglob, o setopt no_no_matchlo que hace que el patrón se deje sin cambios).

Es posible que aún desee utilizar lssus opciones. Por ejemplo, lspuede dar indicaciones sobre la naturaleza o los permisos del archivo (directorio, ejecutable, etc.) a través de colores. Es posible que desee mostrar la fecha, el tamaño y la propiedad del archivo ls -l. Vea el manual para muchas más opciones.

El comando tradicional para buscar un archivo en un árbol de directorios es find. Viene con muchas opciones para controlar qué archivos mostrar y qué hacer con ellos. Por ejemplo, para buscar archivos cuyo nombre coincida con el patrón *filename*en el directorio actual y sus subdirectorios e imprimir sus nombres:

find /some/dir -name '*filename*' -print

-printes una acción (la mayoría de las otras acciones consisten en ejecutar un comando en el archivo); si no pones una acción, -printestá implícito. Además, si no especifica ningún directorio para recorrer ( /some/dirarriba), el directorio actual está implícito. La condición -name '*filename'dice enumerar (o actuar) solo los archivos cuyo nombre coincide con ese patrón; Hay muchos otros filtros, como -mtime -1los archivos modificados en las últimas 24 horas. A veces puede omitir las comillas -name '*filename*', pero solo si el comodín no coincide con ningún archivo en el directorio actual (ver arriba). Con todo, la forma corta es

find -name '*filename*'

Otra herramienta útil cuando sabes (parte de) el nombre de un archivo es locate. Esta herramienta consulta una base de datos de nombres de archivos. En los sistemas típicos, se actualiza todas las noches. La ventaja de locateOver find /es que es mucho más rápido. Un inconveniente es que su información puede ser obsoleta. Hay varias implementaciones locateque difieren en su comportamiento en sistemas multiusuario: el locateprograma básico indexa solo archivos de lectura pública (es posible que desee ejecutar el complemento updatedbpara crear una segunda base de datos que indexe todos los archivos de su cuenta); hay otras versiones (mlocate, slocate) que indexan todos los archivos y hacen que el locateprograma filtre la base de datos para devolver solo los archivos que puede ver.

locate filename

A veces cree que un paquete proporciona un archivo en su distribución, conoce (parte de) el nombre del archivo pero no el nombre de su paquete, y desea instalar el paquete. Muchas distribuciones proporcionan una herramienta para eso. En Ubuntu, es apt-file search filename. Para comandos equivalentes en otros sistemas, verifique el Pacman Rosetta .

Gilles 'SO- deja de ser malvado'
fuente
Ojalá pudiera votar esto de nuevo. Solo tenía que buscar esto para otro proyecto esta noche. Gracias de nuevo, @Gilles!
Iszi
6

el equivalente a su ejemplo de DOS sería:

cd /
find . -name \*filename\* -print

Sin -printembargo, en Linux generalmente ya no necesitas el argumento. Si te encuentras trabajando en otros sistemas operativos, puede ser útil saberlo.

Tim Kennedy
fuente
5

Si quieres algo "rápido" , pero no en una situación de misión crítica y solo quieres saber si existe y dónde está, puedes usarlo locate. Mantiene una base de datos de todos los archivos en los directorios en los que le ha pedido que recopile información.

En la instalación predeterminada (en Ubuntu), locateconfigura un crontrabajo diario que escanea el sistema de archivos y actualiza la base de datos ...

Si cree que necesita actualizar la base de datos antes de la próxima actualización cron, generalmente es más rápido findo lssimplemente ejecutarse sudo updatedby luego locate. Definitivamente es más rápido si necesita hacer más búsquedas ... como su nombre lo indica, updatedbactualiza la base de datos que locateusa ...

locatetiene expresiones regulares incorporadas, lo que lo hace muy útil ... Lo usaré finden un script, pero rara vez lo uso finden la línea de comandos. Incluso lo uso locateen scripts (personales) ... por ejemplo.locate -bir "oo.*datt.*mp4$"

locate devuelve las rutas de acceso completas de los archivos coincidentes.

Peter.O
fuente
2
find [path] -name [filename]

Por ejemplo, si quiero buscar en el directorio / home un nombre de archivo que contenga foo, usaría el comando:

find /home -name *foo*

use el comando man findpara obtener más información sobre el comando de búsqueda y los argumentos,

josh-cain
fuente
3
Debe citar o escapar de los *s para evitar que el shell los interprete.
Shawn J. Goff el
¿Es esa distribución / shell específica? Lo ejecuté en Fedora 16 sin escapes y funcionó bien.
josh-cain
1
Hay opciones en algunos depósitos que pasan las estrellas al programa si no coinciden con nada. Intente crear un archivo en su directorio actual que coincida con ese patrón e intente nuevamente el comando.
Shawn J. Goff el