¿Cómo "grep" para un nombre de archivo en lugar del contenido de un archivo?

135

grep se usa para buscar dentro de un archivo para ver si alguna línea coincide con una expresión regular dada. Sin embargo, tengo esta situación: quiero escribir una expresión regular que coincida con el nombre del archivo en sí (y no con el contenido del archivo). Ejecutaré esto desde el directorio raíz del sistema, para encontrar todos los archivos que coinciden con la expresión regular.

Por ejemplo, si quiero encontrar todos los archivos de formulario VB que comienzan con una "f" y terminan con .frm, usaré la expresión regular:

   "f[[:alnum:]]*\.frm"

¿Puede Grep hacer esto? Si no, ¿hay alguna utilidad que me permita hacer esto? Gracias.

Código Azul
fuente

Respuestas:

120

Debe usar en findlugar de grepen este caso.

También se puede usar finden combinación con grepo egrep:

$ find | grep "f[[:alnum:]]\.frm"
Pablo Santa Cruz
fuente
12
Esto es innecesario Buscar tiene esa funcionalidad incorporada con la -regexopción.
Whereswalden
44
es innecesario aquí, pero grep admite perl regex mientras que find no.
Dan
2
No, puedes usar grep. Mucho más fácil que usar find. Agregue el modificador "-rl" y buscará el nombre del archivo en lugar del archivo. Vea mi publicación a continuación.
RM
@ alpha_989, le dije que grep lo admite, lo que hace: gnu.org/software/grep/manual/html_node/… el punto es que la tubería a grep solo es necesaria si necesita pcre. Whereswalden tiene la respuesta correcta
Dan
60

Ejemplo

find <path> -name *FileName*

Del manual:

patrón de buscar nombre

La base del nombre del archivo (la ruta con los directorios iniciales eliminados) coincide con el patrón de patrón de shell. Debido a que los directorios iniciales se eliminan, los nombres de archivo considerados para una coincidencia con -name nunca incluirán una barra inclinada, por lo que "-name a / b" nunca coincidirá con nada (probablemente deba usar -path en su lugar). Los metacaracteres ("*", "?" Y "[]") coinciden con "." al comienzo del nombre base (esto es un cambio en find-utils-4.2.2; vea la sección CONFORMIDAD DE ESTÁNDARES a continuación). Para ignorar un directorio y los archivos debajo de él, use -prune; vea un ejemplo en la descripción de -path. Los brackets no se reconocen como especiales, a pesar del hecho de que algunos shells, incluido Bash, imponen brackets con un significado especial en los patrones de shell. La coincidencia de nombre de archivo se realiza con el uso de la función de biblioteca fnmatch (3). No olvide encerrar el patrón entre comillas para protegerlo de la expansión del shell.

javaPlease42
fuente
2
Encontré esta respuesta como la más útil. Agregué un par de opciones adicionales: find . -maxdepth 1 -name "*filename*" -print
JSON C11
47

Como dijo Pablo, debe usarlo en findlugar de hacerlo grep, pero no es necesario findhacerlo grep. findtiene esa funcionalidad incorporada:

find . -regex 'f[[:alnum:]]\.frm'

findes un programa muy poderoso para buscar archivos por nombre y admite búsquedas por tipo de archivo, limitación de profundidad, combina diferentes términos de búsqueda con operaciones booleanas y ejecuta comandos arbitrarios en archivos encontrados. Consulte la página del manual de búsqueda para obtener más información.

Whereswalden
fuente
1
-mtime-mmin
Agregaría la
1
Además, el modificador -regex realiza coincidencias con toda la ruta. Entonces, para funcionar, el ejemplo debe agregar. * Al comienzo de la expresión regular.
tumasgiu
15

Puede encontrar la ruta completa de un archivo usando grep, solo canalice la salida del árbol

tree -f | grep filename

Aquí hay una función que puede poner en su .bash_profile o .bashrc

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
jasonleonhard
fuente
-f es opcional.
jasonleonhard
10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

tipos type_descriptor: -

f: archivo normal

d: directorio

l: enlace simbólico

c: dispositivos de caracteres

b: bloquear dispositivos

Sireesh Yarlagadda
fuente
1
Parece que no puedo usar un nombre de archivo después de -type typedescriptorsolo. ¿Es esto un error?
Allan Nørgaard
5

También puedes hacer:

tree | grep filename

Esto canaliza la salida del comando del árbol a grep para una búsqueda. Sin embargo, esto solo le indicará si el archivo existe.

Cayo
fuente
1

No, grep funciona bien para esto:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"
RM
fuente
1
Esto busca el contenido del archivo para "nombre de archivo", luego imprime los nombres de los archivos con coincidencias. OP quiere que coincidan los nombres de los archivos, no los contenidos del archivo.
Matthew
1
De acuerdo, esto no busca nombres de archivos, solo imprime los nombres de los nombres de archivos para los que se encuentra contenido coincidente. Has entendido mal las opciones -ly -Lconsiderablemente.
Prometeo
2
+1 por ser exactamente lo que necesito. Feliz de no tener que criticar la pregunta para encontrar la respuesta que necesitaba
Alexander McNulty
-1

También para múltiples archivos.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
DimiDak
fuente
-1

La forma más fácil es

find . | grep test

aquí find enumerará todos los archivos en el directorio (.), es decir, actual, de forma recursiva. Y luego es solo un simple grep. Aparecerán todos los archivos cuyo nombre tiene "prueba".

Puedes jugar con grep según tus necesidades. Nota: Como grep es una clasificación de cadena genérica, puede dar como resultado no solo nombres de archivo. pero si una ruta tiene un directorio ('/xyz_test_123/other.txt') también vendría al conjunto de resultados. salud

sachyy
fuente
Esto encontrará cualquier cosa con "prueba" en la ruta, por ejemplo ./foo/bar/latest/fred.txt.
Paul R
Oh. Ese en el que no pensé. Gracias por mencionar
sachyy