txt - Encuentra un archivo en python
rutas de archivos en python (7)
En Python 3.4 o posterior, puedes usar pathlib para hacer globbing recursivo:
>>> import pathlib
>>> sorted(pathlib.Path(''.'').glob(''**/*.py''))
[PosixPath(''build/lib/pathlib.py''),
PosixPath(''docs/conf.py''),
PosixPath(''pathlib.py''),
PosixPath(''setup.py''),
PosixPath(''test_pathlib.py'')]
Referencia: https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob
En Python 3.5 o posterior también puedes hacer globbing recursivo de la siguiente manera:
>>> import glob
>>> glob.glob(''**/*.txt'', recursive=True)
[''2.txt'', ''sub/3.txt'']
Referencia: https://docs.python.org/3/library/glob.html#glob.glob
Tengo un archivo que puede estar en un lugar diferente en la máquina de cada usuario. ¿Hay alguna forma de implementar una búsqueda del archivo? ¿De qué manera puedo pasar el nombre del archivo y el árbol del directorio para buscar?
Para una búsqueda rápida e independiente del sistema operativo, use scandir
https://github.com/benhoyt/scandir/#readme
Lee http://bugs.python.org/issue11406 para obtener más información sobre por qué.
Si está trabajando con Python 2, tiene un problema con la recursión infinita en Windows causada por enlaces simbólicos autorreferenciales.
Este script evitará seguirlos. Tenga en cuenta que esto es específico de Windows !
import os
from scandir import scandir
import ctypes
def is_sym_link(path):
# http://.com/a/35915819
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
return os.path.isdir(path) and (ctypes.windll.kernel32.GetFileAttributesW(unicode(path)) & FILE_ATTRIBUTE_REPARSE_POINT)
def find(base, filenames):
hits = []
def find_in_dir_subdir(direc):
content = scandir(direc)
for entry in content:
if entry.name in filenames:
hits.append(os.path.join(direc, entry.name))
elif entry.is_dir() and not is_sym_link(os.path.join(direc, entry.name)):
try:
find_in_dir_subdir(os.path.join(direc, entry.name))
except UnicodeDecodeError:
print "Could not resolve " + os.path.join(direc, entry.name)
continue
if not os.path.exists(base):
return
else:
find_in_dir_subdir(base)
return hits
Devuelve una lista con todas las rutas que apuntan a los archivos en la lista de nombres de archivo. Uso:
find("C://", ["file1.abc", "file2.abc", "file3.abc", "file4.abc", "file5.abc"])
Si está usando Python en Ubuntu y solo quiere que funcione en Ubuntu, una forma sustancialmente más rápida es usar el programa de locate
la terminal de esta manera.
import subprocess
def find_files(file_name):
command = [''locate'', file_name]
output = subprocess.Popen(command, stdout=subprocess.PIPE).communicate()[0]
output = output.decode()
search_results = output.split(''/n'')
return search_results
search_results
es una list
de las rutas absolutas de archivos. Esto es 10.000 veces más rápido que los métodos anteriores y en una búsqueda que hice fue ~ 72,000 veces más rápido.
Vea el módulo os para os.walk o os.listdir
Consulte también esta pregunta os.walk sin profundizar en los directorios a continuación para ver el código de muestra
os.walk es la respuesta, esto encontrará la primera coincidencia:
import os
def find(name, path):
for root, dirs, files in os.walk(path):
if name in files:
return os.path.join(root, name)
Y esto encontrará todas las coincidencias:
def find_all(name, path):
result = []
for root, dirs, files in os.walk(path):
if name in files:
result.append(os.path.join(root, name))
return result
Y esto coincidirá con un patrón:
import os, fnmatch
def find(pattern, path):
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
find(''*.txt'', ''/path/to/dir'')
os.walk
una versión de os.walk
y en un directorio más grande obtuve tiempos de alrededor de 3.5 segundos. Probé dos soluciones aleatorias sin grandes mejoras, y luego lo hice:
paths = [line[2:] for line in subprocess.check_output("find . -iname ''*.txt''", shell=True).splitlines()]
Si bien es POSIX-only, obtuve 0.25 segundos.
A partir de esto, creo que es completamente posible optimizar mucho la búsqueda completa de una manera independiente de la plataforma, pero aquí es donde detuve la investigación.