[英]How to list all directories that do not contain a file type?
我试图返回所有目录的唯一列表( 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
这是您想要的吗?
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()
要获取文件扩展名:
name,ext = os.path.splitext(os.path.join(directory,item))
if ext not in out_list:
job_folders.add(item[:8])
您是否从其他地方复制并粘贴了现有代码? 因为该文档字符串似乎是os.walk
的文档字符串,所以...
您的问题在以下几点上不清楚:
list
和set
是不同的数据结构。 job_folders
是一set
包含数字的文件夹名称,而folder_paths
是包含文件夹的完整路径的list
,无论它们是否包含数字。 34567891
在结果,而不是 region3
的结果。 不管定义是否是递归的, 都应将region3
包括在结果中,因为region3
不包含任何带有列出的扩展名的文件。 job_folders
吗? 我的解决方案假设后者 我要强调的一种糟糕的做法是您使用全局变量out_list
和job_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'])
如您所见,输出folder_paths
中不包含region1\\12345678
和region2\\23456789\\test
,因为它们确实 直接包含指定扩展名的文件。 所有其他子目录都包含在输出中,因为它们不 直接包含指定扩展名的文件。
感谢@DanLenski和@NoctisSkytower,我得以解决这个问题。 当in_path
时,我的WorkOrder
目录始终位于第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 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.