如何列出所有不包含文件类型的目录?

时间:2015-07-10 17:11:34

标签: python directory subdirectory os.walk

如果它们不包含某些文件类型,我正在尝试返回所有目录的唯一列表(set)。如果找不到该文件类型,请将该目录名称添加到列表中以进行进一步审核。

以下功能将查找所有有效文件夹并将其添加到一组以进行进一步比较。我想扩展它只返回那些不包含out_list中文件的目录。这些目录可以包含out_list中包含文件的子目录。如果那是真的,我只想要有效目录的文件夹名称的路径。

# directory = r'w:\workorder'
#
# Example:
# w:\workorder\region1\12345678\hi.pdf
# w:\workorder\region2\23456789\test\bye.pdf
# w:\workorder\region3\34567891\<empty>
# w:\workorder\region4\45678912\Final.doc
# 
# Results:
# ['34567891', '45678912']

job_folders = set([]) #set list is unique
out_list = [".pdf", ".ppt", ".txt"]

def get_filepaths(directory):
    """
    This function will generate the file names in a directory
    tree by walking the tree either top-down or bottom-up. For each
    directory in the tree rooted at directory top (including top itself),
    it yields a 3-tuple (dirpath, dirnames, filenames).
    """

    folder_paths = []  # List which will store all of the full filepaths.

    # Walk the tree.

    for item in os.listdir(directory):
        if os.path.isdir(os.path.join(directory, item)):
            folderpath = os.path.join(directory, item) # Join the two strings in order to form the full folderpath.
            if re.search('^[0-9]', item):
                job_folders.add(item[:8])
            folder_paths.append(folderpath)  # Add it to the list.
    return folder_paths

4 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

import os

def main():
    exts = {'.pdf', '.ppt', '.txt'}
    for directory in get_directories_without_exts('W:\\workorder', exts):
        print(directory)

def get_directories_without_exts(root, exts):
    for root, dirs, files in os.walk(root):
        for file in files:
            if os.path.splitext(file)[1] in exts:
                break
        else:
            yield root

if __name__ == '__main__':
    main()

编辑:在查看了您的要求后,我决定创建一个树对象来分析您的目录结构。一旦创建,使用缓存进行递归查询很简单,以查明目录是否“正常”。从那里,创建一个只能找到“不好”的顶级目录的生成器非常简单。可能有更好的方法可以做到这一点,但代码至少应该有效。

import os

def main():
    exts = {'.pdf', '.ppt', '.txt'}
    for directory in Tree('W:\\workorder', exts).not_okay:
        print(directory)

class Tree:

    def __init__(self, root, exts):
        if not os.path.isdir(root):
            raise ValueError('root must be a directory')
        self.name = root
        self.exts = exts
        self.files = set()
        self.directories = []
        try:
            names = os.listdir(root)
        except OSError:
            pass
        else:
            for child in names:
                path = os.path.join(root, child)
                if os.path.isfile(path):
                    self.files.add(os.path.splitext(child)[1])
                elif os.path.isdir(path):
                    self.directories.append(self.__class__(path, exts))
        self._is_okay = None

    @property
    def is_okay(self):
        if self._is_okay is None:
            self._is_okay = any(c.is_okay for c in self.directories) or \
                            any(c in self.exts for c in self.files)
        return self._is_okay

    @property
    def not_okay(self):
        if self.is_okay:
            for child in self.directories:
                for not_okay in child.not_okay:
                    yield not_okay
        else:
            yield self.name

if __name__ == '__main__':
    main()

答案 1 :(得分:0)

获取文件扩展名:

name,ext = os.path.splitext(os.path.join(directory,item))
if ext not in out_list:
    job_folders.add(item[:8])

答案 2 :(得分:0)

您是否从其他地方复制并粘贴了现有代码?因为docstring似乎是os.walk ...

的文档字符串

您的问题在以下几点尚不清楚:

  1. 您声明代码的目标是&#34;如果它们不包含某些文件类型&#34;则返回所有目录的唯一列表(集)。
    • 首先,listset是不同的数据结构。
    • 其次,您的代码会创建其中一个job_folders是包含数字的set文件夹名称,而folder_pathslist文件夹的完整路径,无论它们是否包含数字。
    • 实际想要什么作为输出?
  2. 应该&#34;那些不包含out_list中的文件的目录&#34;是递归定义的,还是只包含那些目录的第一级内容? 我的解决方案假设后者
    • 您的示例在这一点上是矛盾的:它在结果中显示34567891,但在结果中显示 region3。无论定义是递归的,region3 都应包含在结果中,因为region3不包含任何带有列出的扩展名的文件。
  3. job_folders是仅应填充满足其内容标准的目录,还是使用包含数字的所有文件夹名称填充? 我的解决方案假设后者
  4. 我强调的一个poor practice in your code是您使用全局变量out_listjob_folders我已将前者更改为get_filepaths的第二个参数,将后者更改为第二个返回值。

    无论如何,这是解决方案......

    import os, re
    
    ext_list = [".pdf", ".ppt", ".txt"]
    
    def get_filepaths(directory, ext_list):
        folder_paths = []  # List which will store all of the full filepaths.
        job_folders = set([])
    
        # Walk the tree.
    
        for dir, subdirs, files in os.walk(directory):
            _, lastlevel = os.path.split(dir)
            if re.search('^[0-9]', lastlevel):
                job_folders.add(lastlevel[:8])
    
            for item in files:
                root, ext = os.path.splitext(item)
                if ext in ext_list:
                    break
            else:
                # Since none of the file extensions matched ext_list, add it to the list of folder_paths
                folder_paths.append(os.path.relpath(dir, directory))
    
        return folder_paths, job_folders
    

    我在/tmp下创建了与您的目录结构完全相同的目录结构,并执行以下操作:

    folder_paths, job_folders = get_filepaths( os.path.expandvars(r"%TEMP%\workorder"), ext_list )
    
    print "folder_paths =", folder_paths
    print "job_folders =", job_folders
    

    这是输出:

    folder_paths = ['.', 'region1', 'region2', 'region2\\23456789', 'region3', 'region3\\34567891', 'region4', 'region4\\456789123']
    job_folders = set(['12345678', '23456789', '34567891', '45678912'])
    

    正如您所看到的,region1\12345678region2\23456789\test 包含在输出folder_paths中,因为他们执行 直接包含指定扩展名的文件;所有其他子目录 包含在输出中,因为 直接包含指定扩展名的文件。

答案 3 :(得分:0)

感谢@DanLenski和@NoctisSkytower我能够解决这个问题。 步行WorkOrder时我的in_path目录始终是第7个文件夹,我发现使用os.sep
我借鉴了你的两个解决方案,并提出了以下建议:

import os, re

ext_list = [".pdf"]
in_path = r'\\server\E\Data\WorkOrder'

def get_filepaths(directory, ext_list):
    not_okay = set([])  # Set which will store Job folder where no ext_list files found
    okay = set([]) # Set which will store Job folder where ext_list files found
    job_folders = set([]) #valid Job ID folder

    # Walk the tree.
    for dir, subdirs, files in os.walk(directory):

        for item in files:
            root, ext = os.path.splitext(item)

            if len(dir.split(os.sep)) >= 8: #Tree must contain Job ID folder
                job_folder = dir.split(os.sep)[7]
                if ext in ext_list:
                    okay.add(job_folder)
                else: # Since none of the file extensions matched ext_list, add it to the list of folder_paths
                    not_okay.add(job_folder)

    bad_list = list(not_okay - okay)
    bad_list.sort()

    return bad_list

bad_list = get_filepaths( os.path.expandvars(in_path), ext_list )