Sé que podemos usar os.walk()
para enumerar todos los subdirectorios o todos los archivos de un directorio. Sin embargo, me gustaría enumerar el contenido completo del árbol de directorios:
- Subdirectory 1:
- file11
- file12
- Sub-sub-directory 11:
- file111
- file112
- Subdirectory 2:
- file21
- sub-sub-directory 21
- sub-sub-directory 22
- sub-sub-sub-directory 221
- file 2211
¿Cuál es la mejor manera de lograr esto en Python?
ValueError: zero length field name in format
se lanza.root.replace(startpath, '', 1)
debería arreglar esoSimilar a las respuestas anteriores, pero para python3, posiblemente legible y posiblemente extensible:
Uso de ejemplo:
Salida de ejemplo:
Notas
Editar:
fuente
Una solución sin su sangría:
os.walk ya realiza la caminata de arriba hacia abajo, primero en profundidad que está buscando.
Ignorar la lista de directorios evita la superposición que menciona.
fuente
NameError: name 'path' is not defined
Por lo general, preferimos usar el árbol GNU, pero no siempre lo tenemos
tree
en todos los sistemas y, a veces, Python 3 está disponible. Una buena respuesta aquí podría copiarse y pegarse fácilmente y no convertir a GNU entree
un requisito.tree
La salida se ve así:Creé la estructura de directorio anterior en mi directorio de inicio en un directorio al que llamo
pyscratch
.También veo otras respuestas aquí que se acercan a ese tipo de resultado, pero creo que podemos hacerlo mejor, con un código más simple y moderno y enfoques de evaluación perezosa.
Árbol en Python
Para empezar, usemos un ejemplo que
Path
objeto Python 3yield
yyield from
(que crean una función generadora)y ahora:
huellas dactilares:
Necesitamos materializar cada directorio en una lista porque necesitamos saber cuánto tiempo tiene, pero luego tiramos la lista. Para una recursividad amplia y profunda, esto debería ser lo suficientemente lento.
El código anterior, con los comentarios, debería ser suficiente para comprender completamente lo que estamos haciendo aquí, pero siéntase libre de revisarlo con un depurador para asimilarlo mejor si es necesario.
Más características
Ahora GNU
tree
nos brinda un par de características útiles que me gustaría tener con esta función:n directories, m files
-L level
-d
Además, cuando hay un árbol enorme, es útil limitar la iteración (por ejemplo, con
islice
) para evitar bloquear su intérprete con texto, ya que en algún momento la salida se vuelve demasiado detallada para ser útil. Podemos hacer esto arbitrariamente alto por defecto, digamos1000
.Así que eliminemos los comentarios anteriores y completemos esta funcionalidad:
Y ahora podemos obtener el mismo tipo de resultado que
tree
:huellas dactilares:
Y podemos restringir a niveles:
huellas dactilares:
Y podemos limitar la salida a directorios:
huellas dactilares:
Retrospectivo
En retrospectiva, podríamos haber utilizado
path.glob
para emparejar. Quizás también podríamos usarlopath.rglob
para el globbing recursivo, pero eso requeriría una reescritura. También podríamos usaritertools.tee
lugar de materializar una lista de contenidos de directorio, pero eso podría tener compensaciones negativas y probablemente haría el código aún más complejo.¡Los comentarios son bienvenidos!
fuente
elif not limit_to_directories:
agregue lo siguiente:info = prefix + pointer + path.name; try: with path.open('r') as f: n_lines = len(f.readlines()); loc = f' LOC: {n_lines}'; info += loc; except UnicodeDecodeError: pass; yield info
Consulte este enlace para ver los espacios en blanco adecuados.contents
debe filtrarse silimit_to_directories
es Verdadero. De lo contrario, si una carpeta no tiene un directorio para el último archivo, el árbol no se dibujará correctamente.if limit_to_directories: contents = [path for path in contents if path.is_dir()]
list(dir_path.iterdir())
devolver un árbol de estructura de directorios de arriba hacia abajo ordenado correctamente. No veo tal garantía en la API para iterdir () . Proporcione una referencia sobre cómo se realiza eliterdir()
pedido o se garantiza que proporcionará el pedido deseado.os.listdir()
de forma predeterminada , lo que no garantiza el orden : "La lista está en un orden arbitrario y no incluye las entradas especiales '.' y '..' incluso si están presentes en el directorio. "Vine aquí buscando lo mismo y usé la respuesta dhobbs para mí. Como una forma de agradecer a la comunidad, agregué algunos argumentos para escribir en un archivo, como pidió akshay, e hice que mostrar archivos sea opcional para que no sea una salida. También hizo que la sangría sea un argumento opcional para que pueda cambiarlo, ya que a algunos les gusta que sea 2 y otros prefieren 4.
Usó diferentes bucles para que el que no muestra archivos no verifique si tiene que hacerlo en cada iteración.
Espero que ayude a alguien más como la respuesta de dhobbs me ayudó. Muchas gracias.
fuente
Basado en esta fantástica publicación
http://code.activestate.com/recipes/217212-treepy-graphically-displays-the-directory-structur/
Aquí hay un refinamiento para comportarse exactamente como
http://linux.die.net/man/1/tree
fuente
Si alguien está interesado, esa función recursiva devuelve una estructura anidada de diccionarios. Las claves son
file system
nombres (de directorios y archivos), los valores son:file_token
)Las cadenas que designan archivos están vacías en este ejemplo. También se les puede dar, por ejemplo, el contenido del archivo o la información o privilegios de su propietario o cualquier objeto diferente a un dictado. A menos que sea un diccionario, se puede distinguir fácilmente de un "tipo de directorio" en operaciones posteriores.
Tener un árbol así en un sistema de archivos:
El resultado será:
Si te gusta, ya he creado un paquete (python 2 y 3) con estas cosas (y un buen
pyfakefs
ayudante): https://pypi.org/project/fsforge/fuente
Además de la respuesta de dhobbs anterior ( https://stackoverflow.com/a/9728478/624597 ), aquí hay una funcionalidad adicional para almacenar resultados en un archivo (yo personalmente lo uso para copiar y pegar en FreeMind para tener una buena descripción general de la estructura, por lo tanto, usé pestañas en lugar de espacios para la sangría):
fuente
Puede ejecutar el comando 'árbol' del shell de Linux.
Instalación:
Usando en Python
Ejemplo:
Esto le brinda una estructura más limpia y es visualmente más completo y fácil de escribir.
fuente
Esta solución solo funcionará si la ha
tree
instalado en su sistema. Sin embargo, dejo esta solución aquí en caso de que ayude a alguien más.Puede indicarle al árbol que genere la estructura del árbol como XML (
tree -X
) o JSON (tree -J
). Por supuesto, JSON se puede analizar directamente con python y XML se puede leer fácilmentelxml
.Con la siguiente estructura de directorios como ejemplo:
XML
JSON
fuente
Quizás más rápido que @ellockie (Quizás)
Resultados de la prueba en la captura de pantalla a continuación:
fuente
Aquí puede encontrar un código con un resultado como este: https://stackoverflow.com/a/56622847/6671330
fuente
Para aquellos que todavía buscan una respuesta. Aquí hay un enfoque recursivo para obtener las rutas en un diccionario.
fuente
¡La respuesta de @dhobbs es genial!
pero simplemente cambia para obtener fácilmente la información del nivel
y la salida como
¡puedes obtener el nivel por
|
conteo!fuente