답변:
os.walk 가 정답이며 첫 번째 일치 항목을 찾습니다.
import os
def find(name, path):
for root, dirs, files in os.walk(path):
if name in files:
return os.path.join(root, name)
그리고 이것은 모든 일치를 찾을 것입니다 :
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
그리고 이것은 패턴과 일치합니다.
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')
if name in file or name in dirs
for name in files:실패 합니다. (내 인생의 시간은 내가 다시하고 싶은 ;-) 다소 지저분한 수정이super-photo.jpgsuper-photo.JPGif str.lower(name) in [x.lower() for x in files]
나는 버전을 사용하고 os.walk더 큰 디렉토리에서 약 3.5 초를 얻었습니다. 크게 개선되지 않은 두 가지 무작위 솔루션을 시도한 다음 방금 수행했습니다.
paths = [line[2:] for line in subprocess.check_output("find . -iname '*.txt'", shell=True).splitlines()]
POSIX 전용이지만 0.25 초를 얻었습니다.
이로부터 플랫폼 독립적 인 방식으로 전체 검색을 최적화하는 것이 전적으로 가능하다고 생각하지만 여기서 연구를 중단했습니다.
Ubuntu에서 Python을 사용하고 Ubuntu에서만 작동하도록하려면 터미널 locate프로그램을 이와 같이 사용하는 것이 훨씬 더 빠른 방법입니다 .
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_resultsA는 list절대 파일 경로가. 이것은 위의 방법보다 10,000 배 더 빠르며 한 번의 검색에 대해 ~ 72,000 배 더 빠릅니다.
Python 3.4 이상에서는 pathlib를 사용하여 재귀 적 globbing을 수행 할 수 있습니다.
>>> 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')]
참조 : https://docs.python.org/3/library/pathlib.html#pathlib.Path.glob
Python 3.5 이상에서는 다음과 같이 재귀 적 globbing을 수행 할 수도 있습니다.
>>> import glob
>>> glob.glob('**/*.txt', recursive=True)
['2.txt', 'sub/3.txt']
OS 독립적 인 빠른 검색을 위해 scandir
https://github.com/benhoyt/scandir/#readme
읽기 http://bugs.python.org/issue11406을 하는 이유 자세한 내용은.
Python 2로 작업하는 경우 자체 참조 심볼릭 링크로 인해 창에서 무한 재귀 문제가 발생합니다.
이 스크립트는 그것들을 따르지 않을 것입니다. 이것은 Windows 전용입니다 !
import os
from scandir import scandir
import ctypes
def is_sym_link(path):
# http://stackoverflow.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
파일 이름 목록에있는 파일을 가리키는 모든 경로가있는 목록을 반환합니다. 용법:
find("C:\\", ["file1.abc", "file2.abc", "file3.abc", "file4.abc", "file5.abc"])
대답은 기존의 것과 매우 유사하지만 약간 최적화되었습니다.
따라서 패턴별로 모든 파일 또는 폴더를 찾을 수 있습니다.
def iter_all(pattern, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if pattern.match(entry)
)
하위 문자열로 :
def iter_all(substring, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if substring in entry
)
또는 술어 사용 :
def iter_all(predicate, path):
return (
os.path.join(root, entry)
for root, dirs, files in os.walk(path)
for entry in dirs + files
if predicate(entry)
)
파일 만 검색하거나 폴더 만 검색하려면- "dirs + files"를 필요에 따라 "dirs"또는 "files"로만 바꿉니다.
문안 인사.
SARose의 답변은 Ubuntu 20.04 LTS에서 업데이트 할 때까지 저에게 효과적이었습니다. 그의 코드를 약간 변경하여 최신 Ubuntu 릴리스에서 작동합니다.
import subprocess
def find_files(file_name):
file_name = 'chromedriver'
command = ['locate'+ ' ' + file_name]
output = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]
output = output.decode()
search_results = output.split('\n')
return search_results