Cómo buscar archivos recursivamente en subdirectorios

117

Estoy tratando de buscar todos los XMLarchivos en un directorio particular y todos los subdirectorios (recursivamente) dentro de él.

ls -R *.xmlsolo enumera archivos en el directorio actual. Estoy bastante seguro, las subcarpetas tienen varios .xmlarchivos, pero ninguno aparece.

¿Es esto un problema de configuración?

Shamim Hafiz
fuente
2
Puedes hacerlols -R | grep .xml
Nikos

Respuestas:

90

Intenta usar Buscar

sudo find . -print | grep -i '.*[.]xml'
Mitch
fuente
44
¿es el sudo imprescindible o está ahí para garantizar privilegios de superusuario?
Shamim Hafiz
44
Te dejo decidir. Sudo , No Sudo .
Mitch
66
Solo por interés. ¿Cuál es la ventaja de findmás ls -R?
don.joey
1
@ don.joey Esto podría ayudar a stackoverflow.com/questions/13830036/…
Mitch
10
-1 para mezclar findy grep, cuando findpuede filtrar usando expresiones regulares y globos, y no usar find'sy -print0grep' -zcuando necesita mezclar.
muru
147

Puedes hacerlo solo con find :

find . -name '*.xml'

.es el directorio actual Si necesita buscar en otro directorio, reemplácelo .con la ruta del directorio.

KaeruCT
fuente
2
¿Busca el archivo requerido recursivamente en el directorio enraizado en el directorio actual? En mi caso, solo se registró en el directorio actual, no se verificó el subdirectorio.
Mostafiz Rahman
1
@mostafiz, debe citar la parte '* .xml'. Editaré mi respuesta.
KaeruCT
1
En realidad busqué .phparchivos en el directorio actual. Pero solo devolvió .phparchivos en el directorio actual, no buscó recursivamente en subdirectorios. Es por eso que pregunto si el findcomando busca de forma recursiva o no.
Mostafiz Rahman
3
@mostafiz, el findcomando busca de forma recursiva. Si no cita el parámetro, creo que su shell podría expandirse *, por lo que coincidirá con los archivos en el directorio actual.
KaeruCT
¡Todo bien! Puede ser que haya cometido un error. ¡Ahora está funcionando perfectamente!
Mostafiz Rahman
13

Prueba este comando:

ls -R | grep '.*[.]xml'

lsno tiene opciones para filtrar la salida. Para eso necesitarías usar tubería. Esto pasa la salida de lsa grep, que luego los filtra para mostrar solo los .xmlarchivos.

Rohit Jain
fuente
55
¿De todos modos para que esto muestre el directorio del que proviene?
AdamO
1
Enlace obligatorio: ¿Por qué no analizar ls?
Ruslan
4

golpetazo

Usando la globstaropción de shell, podemos hacer uso del engrosamiento recursivo./**/*

bash-4.3$ shopt -s globstar
bash-4.3$ for i in  ./**/*.xml; do printf "%s\n" "$i" ; done
./adwaita-timed.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/META-INF/context.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/beans.xml
./bin/hw5/stuff/book/chapter42servletexample/build/web/WEB-INF/web.xml

Perl

Perl tiene un módulo Findque permite el recorrido recursivo del árbol de directorios. Dentro de la find()función especial , podemos definir una subrutina deseada y el directorio que queremos recorrer, en este ejemplo eso es .. La frase en este caso sería:

bash-4.3$ perl -le 'use File::Find; find(sub{-f && $_ =~ /.xml$/ && print $File::Find::name},".")' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml

Pitón

Si bien Perl tiene un módulo completo dedicado al recorrido recursivo del árbol, Python tiene una función ordenada walk()que forma parte del osmódulo y devuelve repetidamente la tupla de la ruta superior, la lista de todos los subdirectorios y la lista de nombres de archivo. Podemos hacer lo siguiente:

bash-4.3$ python -c 'import os,sys; [ sys.stdout.write(os.path.join(r,i)+"\n") for r,s,f in os.walk(".") for i in f if i.endswith(".xml") ]' 
./adwaita-timed.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/beans.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/jsf2demo/build/web/WEB-INF/web.xml
./CLEAR_DESKTOP/blahblah/hw5/stuff/book/liangweb/build.xml

Esto podría ser mucho más ordenado como script:

#!/usr/bin/env python
import os,sys 
for r,s,f in os.walk("."): 
    for i in f: 
        if i.endswith(".xml") 
             print(os.path.join(r,i))

encontrar

Se han mencionado otras respuestas findpara el recorrido recursivo, y esa es la herramienta de referencia para el trabajo. Lo que sí necesita mencionar es el hecho de que findtiene varios interruptores de línea de comandos, como -printfimprimir la salida en el formato deseado, -type fbuscar solo archivos regulares, -inumbuscar por número de inodo, -mtimebuscar por fecha de modificación, -exec <command> {} \;ejecutar un comando particular para procesar el archivo con el archivo de paso como argumento (donde {}es el findmarcador de posición estándar para el archivo actual), y muchos otros, así que lea la página de manual para find.

Sergiy Kolodyazhnyy
fuente