在 python 中查找文件

2025-01-15 08:46:00
admin
原创
132
摘要:问题描述:我有一个文件,它可能位于每个用户机器的不同位置。有没有办法实现对文件的搜索?有没有办法可以传递文件的名称和目录树进行搜索?解决方案 1:os.walk是答案,这将找到第一个匹配:import os def find(name, path): for root, dirs, files in...

问题描述:

我有一个文件,它可能位于每个用户机器的不同位置。有没有办法实现对文件的搜索?有没有办法可以传递文件的名称和目录树进行搜索?


解决方案 1:

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

解决方案 2:

在 Python 3.4 或更新版本中,你可以使用 pathlib 进行递归通配:

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

解决方案 3:

我使用了一个版本os.walk,在较大的目录上花费的时间约为 3.5 秒。我尝试了两种随机解决方案,但没有什么大的改进,然后就这样做了:

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

虽然它仅限于 POSIX,但我得到了 0.25 秒。

由此,我相信完全有可能以独立于平台的方式对整个搜索进行大量优化,但我停止了研究。

解决方案 4:

如果您在 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('
')

    return search_results

search_resultslist绝对文件路径。这比上述方法快 10,000 倍,对于我进行的一次搜索,它快了约 72,000 倍。

解决方案 5:

如果您正在使用 Python 2,那么您会遇到由自引用符号链接导致的 Windows 无限递归问题。

此脚本将避免遵循这些。请注意,这是特定于 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"])

解决方案 6:

下面我们使用布尔“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 

解决方案 7:

该答案与现有的答案非常相似,但略微进行了优化。

因此,您可以按照模式找到任何文件或文件夹:

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”,具体取决于您的需要。

问候。

解决方案 8:

SARose 的答案对我来说一直有效,直到我从 Ubuntu 20.04 LTS 更新。我对他的代码做了一些小改动,使它可以在最新的 Ubuntu 版本上运行。

import subprocess

def find_files(file_name):
    command = ['locate'+ ' ' + file_name]
    output = subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]
    output = output.decode()
    search_results = output.split('
')
    return search_results

解决方案 9:

@FMF 的答案在这个版本中存在一些问题,因此我做了一些调整以使其正常工作。

import os
from os 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(str(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
                except PermissionError:
                    print("Skipped " + os.path.join(direc, entry.name) + ". I lacked permission to navigate")
                    continue

    if not os.path.exists(base):
        return
    else:
        find_in_dir_subdir(base)

    return hits

unicode() 在 Python 3 中已更改为 str(),因此我进行了调整(第 8 行)

我还添加了(第 25 行)PermissionError 异常。这样,如果程序发现无法访问的文件夹,它就不会停止。

最后,我想给出一点警告。运行程序时,即使你正在寻找单个文件/目录,也请确保将其作为列表传递。否则,你会得到很多不一定与你的搜索相匹配的答案。

使用示例:

查找(“C:\”,[“Python”,“家庭作业”])

或者

查找(“C:\\”,[“家庭作业”])

但是,例如: find("C:\\", "Homework") 将给出不想要的答案。

如果我说我知道为什么会发生这种情况,那我就是在撒谎。再说一遍,这不是我的代码,我只是做了必要的调整让它工作。所有功劳都应归功于@FMF

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2560  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1552  
  华为IPD研发项目管理在企业的创新与发展中扮演着至关重要的角色,而高效复盘则是确保项目不断优化、持续提升的关键环节。通过合理运用一系列工具,华为能够深入剖析项目过程中的得失,为未来项目提供宝贵经验。以下将详细解析助力华为IPD研发项目管理实现高效复盘的5大工具。项目数据仪表盘项目数据仪表盘是一种直观呈现项目关键数据的工...
华为IPD产品开发流程   0  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Hive、Monday、GanttPRO、QuickBase、Planview、Productive、Plutio、Forecast、Runn。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目成功的关键工具。然而,面对市场上琳琅满...
项目管理软件   1  
  PLM(产品生命周期管理)项目管理对于企业产品的全生命周期管控至关重要,而其中资源分配的优化以及高效团队协作机制的构建更是决定项目成败的关键因素。合理的资源分配能确保项目在预算和时间范围内顺利推进,高效的团队协作机制则能充分发挥团队成员的优势,提升整体项目的执行效率。接下来,我们将深入探讨如何通过四个关键步骤来优化资源...
国产plm软件排名   2  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用