python查找,在python中查找文件

在python中查找文件

我有一个文件,可能在每个用户的计算机上的不同位置。 有没有办法实现搜索文件? 我可以通过文件的名称和目录树来搜索的方式吗?

directedition asked 2019-06-11T22:09:17Z

8个解决方案

171 votes

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')

Nadia Alramli answered 2019-06-11T22:09:43Z

18 votes

我使用了os.walk的版本,并在更大的目录上获得了大约3.5秒的时间。 我尝试了两个没有很大改进的随机解决方案,然后就做了:

paths = [line[2:] for line in subprocess.check_output("find . -iname '*.txt'", shell=True).splitlines()]

虽然只有POSIX,但我得到了0.25秒。

由此,我相信完全可能以独立于平台的方式优化整个搜索,但这是我停止研究的地方。

kgadek answered 2019-06-11T22:10:22Z

4 votes

如果您正在使用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"])

F.M.F. answered 2019-06-11T22:10:59Z

2 votes

要进行快速,独立于操作系统的搜索,请使用scandir

[https://github.com/benhoyt/scandir/#readme]

阅读[http://bugs.python.org/issue11406]了解详情。

Dima Tisnek answered 2019-06-11T22:11:37Z

2 votes

如果你在Ubuntu上使用Python并且你只想让它在Ubuntu上工作,那么使用终端的search_results这样的程序要快得多。

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是绝对文件路径的list。 这比上述方法快10,000倍,对于一次搜索我已经完成了大约72,000倍。

SARose answered 2019-06-11T22:12:09Z

1 votes

在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或更新版本中,您也可以像这样执行递归通配:

>>> import glob

>>> glob.glob('**/*.txt', recursive=True)

['2.txt', 'sub/3.txt']

参考:[https://docs.python.org/3/library/glob.html#glob.glob]

Kenyon answered 2019-06-11T22:12:54Z

0 votes

请参阅os模块的os.walk或os.listdir

另请参阅此问题os.walk而不深入下面的目录以获取示例代码

Martin Beckett answered 2019-06-11T22:13:25Z

0 votes

下面我们使用布尔“first”参数在第一个匹配和所有匹配之间切换(默认值相当于“find.-name file”):

import os

def find(root, file, first=False):

for d, subD, f in os.walk(root):

if file in f:

print("{0} : {1}".format(file, d))

if first == True:

break

Leon Chang answered 2019-06-11T22:13:50Z