Python系统交互 | 0 按指定规则查找目录下所有文件

  当我们批量进行文件处理时,往往需要程序自动读取某一文件夹下某一类型的所有文件。

例如:当我们需要对文件夹下所有的 ∗ * .tif 文件进行裁剪操作,此时,就需要找到文件夹下所有的 ∗ * .tif 文件,然后逐个裁剪输出。因此,查找文件夹下所有的 ∗ * .tif 文件是批量裁剪首要解决的问题

  本文提供两种批量查找文件的方法:1)一种采用os库来进行,2)另一种采用glob库(推荐方法)通过通配符的方式查找。并提供相应的基础示例,由简单到复杂,方便理解。除此之外,还针对两种库构造函数实例,实现获取全部文件夹、文件等多种高级搜索功能,甚至还能查找含有固定字符的文件或文件夹,方便应用时直接调用,简化应用过程。

0 关键字

  遍历,文件,os,glob,通配符

1 主要思路

开始
获取所有的文件路径
判断文件类型
保留所需文件
结束

2 示例数据

  1)定义查找文件夹路径

Path = r'D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件'

注意: \为特殊字符,加上r后表示不进行转义,Python才能正常识别此路径。当然,路径表述还有其他的方式,例如:
  利用 \\:Path = ‘D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件’
  利用 / / /:Path = ‘D:/CSDN/Python系统交互/0 按指定规则查找目录下所有文件’
这几种方式等效

  2)示例文件组织方式
  文件夹下有3个txt文件、1个csv文件和一个子文件夹 [其他],子文件夹 [其他] 下有一个txt文件和一个csv文件。文件组织方式如下:

0 按指定规则查找目录下所有文件
----其他
-------201805.txt
-------201806.csv
----201801.txt
----201802.txt
----201803.txt
----201804.csv

3 os方法

  首先导入os库。

import os

3.1 基础:提取文件夹下指定扩展名的文件

任务目标:提取 [Path] 下所有 txt 文件(不包含子文件夹 [其他] 下的 txt 文件)。
预期结果:返回:
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201801.txt
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201802.txt
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201803.txt

  1)获取所有文件和文件夹路径(不包括子文件夹下的项)

Files = os.listdir(Path)

  2)获取所有 txt 文件
  基础:利用for循环

NeedFiles = []  # 创建一个空列表存储最终的结果
for File in Files:
	if File.endswith('.txt'):
		# 通过os.path.join将Path与文件名File组合为完整文件路径,并将结果添加到NeedFilse
		NeedFiles.append(os.path.join(Path,File))  
print(NeedFiles)

  优化:构造列表解析式

NeedFiles = [os.path.join(Path,File) for File in Files if File.endswith('.txt')]
print(NeedFiles)

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt']

3.2 进阶:提取文件夹及其子文件夹下所有指定扩展名的文件

任务目标:提取 [Path] 及其子文件夹 [其他] 下所有 txt 文件。
预期结果:返回:
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201801.txt
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201802.txt
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201803.txt
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\其他\201805.txt

  基础:利用for循环

NeedFiles = []
for Root, Folders, FileNames in os.walk(Path):
    for FileName in FileNames:
        if FileName.endswith('.txt'):
            NeedFiles.append(os.path.join(Root, FileName))
print(NeedFiles)

其中 Folders为子文件夹集合,FileNames为子文件集合。如果需要获取子文件夹,则将for FileName in FileNames部分改为for Folder in Folders,按照需求判断即可。

  练习1:利用 列表解析式 优化 本节提取过程。
  练习2:获取所有子文件夹路径。

  当然,正则表达式(regular expression) 也可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
  探索:利用re库构建正则表达式匹配文件。有兴趣的朋友可以尝试。

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201805.txt']

3.3 高阶:构造 GetPath 函数实现获取全部文件夹、文件的功能

此函数可实现对1个或多个文件夹内(SearchPath)所需类型(SearchType)和指定扩展名(EXT)文件的查找,函数整体是对本章前两节所述内容的扩展,有兴趣的朋友可自行调用测试,也欢迎对其进行改造优化。

def GetPaths(SearchPath, SearchType = 'FILE', EXT = None):
    '''
    简介
    ----------
    获取目标 【路径或路径集合】 下满足条件的所有 【文件夹或(和)文件路径】。
    
    参数
    ----------
    SearchPath: str 或 list。路径或路径列表。可以是:       
    
        1.路径(str)。 例:'C:/SP' 或 'C:/SP/test.txt'。   
            
        2.路径集合(list)。 例: ['C:/SD', 'C:/SP', 'C:/SP/test.txt']  
             
        注:如果目标路径或路径集合中包含文件,则会判断文件是否存在,如果文件不存在,返回结果会将此文件路径清除。   
         
    **可选参数
    ----------  
    SearchType = str。要查找路径的类型,默认为查找文件('FILE')。   
     
        其他类型包括'DIR'(文件夹),'ALL'(文件夹和文件)。如果设置的值不为以上所有类型,则认为是'ALL'。  
        
    EXT = str。查找文件的扩展名。只有在 SearchPath = 'FILE' 时, 此参数才生效。默认查找所有文件(None)。   
         
    返回
    ----------
    类型:list。满足条件的所有 【文件夹和文件路径】集合。重复的路径只会保留一个。
    
    '''   
       
    def GetALLPath(SearchPath): # 获取所有文件和文件夹路径。
        PathsList = [] 
        
        if isinstance(SearchPath, list) is False: # 如果参数不是列表,则将其转为列表  
            SearchPath = list([SearchPath])
            
        for SubPath in SearchPath: # 遍历列表内所有项
        
            if os.path.isdir(SubPath): # 如果是文件夹,则按照 4.2 的思路查找所有文件和文件夹
                for Root, Folders, FileNames in os.walk(SubPath):
                    for Folder in Folders:
                        PathsList.append(os.path.join(Root, Folder))   
                    for FileName in FileNames:
                        PathsList.append(os.path.join(Root, FileName))
                        
            else: # 如果是文件,且文件存在,则直接记录文件路径
                if os.path.exists(SubPath):
                    PathsList.append(SubPath)
                    
        return list(set(PathsList))
        
    def GetSubPath(): 
        OutList = []
        for Path in PathsList: # 遍历 PathsList 列表内的所有项
        	# 如果SearchType参数(忽略大小写)为'DIR'则记录文件夹。
            if SearchType.upper() == 'DIR': 
                if os.path.isdir(Path): 
                    OutList.append(Path) 
            else:
            	# 如果未设置扩展名则保留所有文件,否则保留指定扩展名的文件。
                if os.path.isfile(Path): 
                    if EXT is None: 
                        OutList.append(Path)
                    else:
                        if Path.lower().endswith(EXT.lower()):
                            OutList.append(Path)         
        return OutList   
                        
    PathsList = GetALLPath(SearchPath)
    
    # 如果SearchType不为'DIR'或'FILE',则返回所有文件和文件夹路径(本例结果均包含子文件和子文件夹)。
    if SearchType.upper() != 'DIR' and SearchType.upper() != 'FILE':
        return PathsList
    else:      
        return GetSubPath()

  引用:

NeedFiles = GetPath(Path, EXT = '.txt')
print(NeedFiles)

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201805.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201801.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201803.txt',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201802.txt']

4 glob方法(推荐)

  首先导入os、glob库。

import os
import glob

4.1 入门:常用通配符简介

通配符简介
*匹配零个或多个字符,但不匹配"."开头的文件。
?仅匹配其中某一个单字符。
[]匹配括号内的任意单字符,可使用“-”符号表示一个范围。例如:[0-9]:匹配数字范围;[a-z]:匹配字母范围。
**匹配所有字符。glob进行递归操作时设置此通配符才能生效。

4.2 基础:使用通配符获取指定扩展名的文件

任务目标:提取 [Path] 下所有 csv 文件(不包含子文件夹 [其他] 下的 csv 文件)。
预期结果:返回:
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201804.csv

Files = glob.glob(Path+'\*.csv')
print(Files)

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv']

4.3 进阶:使用通配符获取文件夹及子文件下指定扩展名的文件

任务目标:提取 [Path] 及其子文件夹 [其他] 下所有 csv 文件。
预期结果:返回:
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\201804.csv
  D:\CSDN\Python系统交互\0 按指定规则查找目录下所有文件\其他\201806.csv

Files = glob.glob(Path+'\**\*.csv', recursive = True) # recursive 是否进行递归。
print(Files)

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201806.csv']

4.4 高阶:利用glob库构造GetPath函数实现高级查找功能

推荐使用该函数实现查找功能。该函数可以以一个或多个文件夹为查找目标(Path),实现文件、文件夹、文件和文件夹查找(Search);查找文件时可提供扩展名(EXT),获取目标类型的文件;同时,也能够根据文件包含的字符串(String),实现精确查找。当然,EXT和String参数也可为列表,实现多类型,多字符串的同时匹配,满足多种查找需求。另外,如果大家有其他更好的想法,也欢迎反馈和讨论。

def GetPath(Path, Search = 'FILE', EXT = None, String = None):
    '''
    简介
    ----------
    获取目标 【路径或路径集合】 下满足条件的所有 【文件夹和(或)文件路径】。

    参数
    ----------
    Path: str 或 list。路径或路径集合。可以是:

        1.路径(str)。 例:'C:/SP'。

        2.路径集合(list)。 例: ['C:/SD', 'C:/SP']
        
    **可选参数
    ----------    
    Search = 'FILE' 或其他类型。要查找路径的类型,默认为查找文件('FILE')。

        其他类型包括'DIR'(文件夹),'ALL'(文件夹和文件)。如果设置的值不为以上所有类型,则认为是 'FILE' 。

    EXT = None 或 str、list。查找文件的扩展名或扩展名列表。只有在Search = 'FILE'时, 此参数才生效。默认查找所有文件(None)。

    String = None 或 str、list。查找的文件路径中包含的字符串或字符串列表。默认不处理此参数(None)。

    返回
    ----------
    类型:list。满足条件的所有 【文件夹和文件路径】集合。

    '''
    # 格式化输入目录
    if isinstance(Path, str):
        Path = [Path]
    elif isinstance(Path, list):
        Path = list(set(Path))
    else:
        return []

    # 格式化通配符规则
    if Search == 'DIR':
        Wildcard =  '/**/'
    elif Search == 'ALL':
        Wildcard =  '/**/*'
    else:
        if EXT is None:
            Wildcard =  '/**/*.*'
        elif isinstance(EXT, list):
            Wildcard = ['/**/*' + E for E in EXT]
        else:
            Wildcard = '/**/*' + EXT

    # 通配所有路径
    if isinstance(Wildcard, list):
        SPath = sum([glob.glob(P + W, recursive = True) for P in Path for W in Wildcard if os.path.exists(P)], [])
    else:
        SPath = sum([glob.glob(P + Wildcard, recursive = True) for P in Path if os.path.exists(P)], [])

    # 提取含设定字符串的路径
    if String is not None:
        if isinstance(String, str):
            String = [String]
        SPath = [P for P in SPath for S in String if S in os.path.basename(P)]

    return SPath

  引用:

NeedFiles = GetPath(Path, EXT = '.csv')
print(NeedFiles)

  打印结果:

['D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\201804.csv',
 'D:\\CSDN\\Python系统交互\\0 按指定规则查找目录下所有文件\\其他\\201806.csv']
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛的地理研学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值