【问题标题】:os.walk folder exclusion based on .txt file基于 .txt 文件的 os.walk 文件夹排除
【发布时间】:2020-02-05 23:04:11
【问题描述】:

我想要一个 Folders_To_Skip.txt 文件,其中包含由新行分隔的目录列表

例如:

A:\\stuff\a\b\
A:\\junk\a\b\

我有一些文件正在破坏我的 .csv 记录编译,我想排除那些我无论如何都不需要阅读的目录。

locate 函数中,我有我试图从Excluding directories in os.walk 实现的功能,但我似乎无法让它与list 中的目录一起使用,更不用说从文本文件列表中读取的时候了print 访问的文件仍然包含我试图排除的目录中的文件。

您能否解释一下解决方案是特定的排除目录(不是世界末日),还是可以操作排除子目录(会更方便)。

现在locate 之前的代码允许轻松查找控制文本文件,然后将这些项目作为列表加载到脚本的其余部分以运行,假设所有控制文件都在同一位置,但位置可以根据运行脚本的人员和位置而改变。

也出于测试目的,Drive_Locations.txt 设置为:

A
B

这是当前脚本:

import os
from tkinter import filedialog
import fnmatch

input('Press Enter to select any file in writing directory or associated control files...')
fname = filedialog.askopenfilename()
fpath = os.path.split(fname)

# Set location for Drive Locations to scan
Disk_Locations = os.path.join(fpath[0], r'Drive_Locations.txt')
# Set location for Folders to ignore such as program files
Ignore = os.path.join(fpath[0], r'Folders_To_Skip.txt')

# Opens list of Drive Locations to be sampled
with open(Disk_Locations, 'r') as Drives:
    Drive = Drives.readlines()
    Drive = [x.replace('\n', '') for x in Drive]
# Iterable list for directories to be excluded
with open(Ignore, 'r') as SkipF1:
    Skip_Fld = SkipF1.readlines()
    Skip_Fld = [x.replace('\n', '') for x in Skip_Fld]

# Locates file in entire file tree from previously established parent directory.
def locate(pattern, root=os.curdir):
    for path, dirs, files in os.walk(os.path.abspath(root), topdown=True):
        dirs[:] = [d for d in dirs if d not in Skip_Fld]
        for filename in fnmatch.filter(files, pattern):
            yield os.path.join(path, filename)

for disk in Drive:
    # Formats Drive Location for acceptance
    disk = str.upper(disk)
    if str.find(disk, ':') < 0:
        disk = disk + ':'
    # Changes the current disk drive
    if os.path.exists(disk):
        os.chdir(disk)
    # If disk incorrect skip to next disk
    else:
        continue
    for exist_csv in locate('*.csv'):
        # Skip compiled record output files in search
            print(exist_csv)

【问题讨论】:

  • 嗨@tv006,欢迎来到该网站。您在这里为我们提供了很多代码,但并不完全清楚您在问什么。在我看来,实现您似乎想要的过滤的最明显的地方是在您正在执行 os.walk 调用的 locate 函数中(它不能在其他任何地方工作),但你没有似乎试图修改dirs。你能从你的例子中删掉一些不相关的代码,或者向我们展示你在目录跳过方面的实际尝试吗?
  • 您确实需要提取并提供minimal reproducible example。作为新用户,请同时关注tour 并阅读How to Ask。特别是,说“我尝试了一些含糊不清的东西”然后说“它没有用”都没有帮助。提供事实,而不是解释。
  • 变量和函数名称应遵循lower_case_with_underscores 样式。不一致的命名和大量的代码使这几乎无法阅读。
  • 我还可以看到一堆可以简化的区域,特别是在程序开始时,您正在阅读所有文件。
  • AMC - 不幸的是,我想不出一个解决方案来清理读取文件的部分,因为我正在尝试设置它,所以同事可以在没有任何编码的情况下运行它,只需检查他们是否想要更改我认为对用户更友好的文本文件。我认为该部分可能受益最多的是某种方式来杀死 Windows 资源管理器搜索弹出的 tk 窗口。

标签: python


【解决方案1】:

这里的主要错误是os.walk() 返回相对目录名称的列表。因此,例如当您在目录A:\stuff\a 中时,您要跳过的目录只是列为b,而不是A:\stuff\a\b;因此,您的跳过逻辑当然不会从当前目录的子目录列表中删除任何内容。

这是一个直接检查当前目录的重构。

for path, dirs, files in os.walk(os.path.abspath(root), topdown=True):
    if path not in Skip_Fld:
        for filename in fnmatch.filter(files, pattern):
            yield os.path.join(path, filename)

abspath 电话很重要;很高兴您将其包含在您的尝试中。

您要跳过的目录列表应该有单个反斜杠,或者可能是正斜杠,并且可能没有最终目录分隔符(幸运的是,我无法检查 Windows 上 os.walk() 是如何报告这些的)。

【讨论】:

  • 我还没有检查脚本的其余部分;可能还有其他错误。
  • 我尝试使用它并修改它以使用 for 循环,因为我确实想要一个可迭代的,但它似乎不起作用。我想知道python如何将读取路径转换为字符串是否可能导致字符串无法操作。我尝试在排除路径上运行尽可能多的格式化选项,但似乎没有任何问题。我什至认为它需要将路径提升一个级别,但这似乎也不起作用。
  • 与其猜测问题,不如添加战略性print 语句以显示变量的值,并与您的预期进行比较。
  • 事情就是这样,基于print 语句的使用,一个路径字符串,当作为字符串列表引入时,输入 =/= 输出。我对这个问题的假设是,我在字符串列表中添加了 path 的等价物,并且在 python 将 path 作为字符串读取的过程中,如果有意义的话,它基本上变成了 path*。因此,Skip_Fld 永远不会包含 path 项目,因为 path* 项目是被迭代的。我之前解决这个问题的唯一方法是使用原始字符串来处理文件路径,但我不知道如何在构建列表中实现它。
  • 同样,如果可以将脚本简化为 minimal reproducible example,并且您可以在问题中提及甚至证明这一观察结果,那么您更有可能获得帮助以达成解决方案。讨厌的 GUI 尤其掩盖了问题,因为很难确切地知道如何重现您的问题。取出所有活动部件,只留下问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2021-02-07
  • 2021-02-13
  • 2021-04-20
相关资源
最近更新 更多