如果它们不包含某些文件类型,我正在尝试返回所有目录的唯一列表(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
答案 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
...
您的问题在以下几点尚不清楚:
list
和set
是不同的数据结构。job_folders
是包含数字的set
文件夹名称,而folder_paths
是list
文件夹的完整路径,无论它们是否包含数字。34567891
,但在结果中显示不 region3
。无论定义是递归的,region3
都应包含在结果中,因为region3
不包含任何带有列出的扩展名的文件。job_folders
是仅应填充满足其内容标准的目录,还是使用包含数字的所有文件夹名称填充? 我的解决方案假设后者 我强调的一个poor practice in your code是您使用全局变量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'])
正如您所看到的,region1\12345678
和region2\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 )