Python 筛选os.walk()目录和文件
我正在寻找一种从Python 筛选os.walk()目录和文件,python,filtering,os.walk,Python,Filtering,Os.walk,我正在寻找一种从os.walk()调用中包括/排除文件模式和目录的方法 以下是我现在正在做的事情: import fnmatch import os includes = ['*.doc', '*.odt'] excludes = ['/home/paulo-freitas/Documents'] def _filter(paths): for path in paths: if os.path.isdir(path) and not path in excludes
os.walk()
调用中包括/排除文件模式和目录的方法
以下是我现在正在做的事情:
import fnmatch
import os
includes = ['*.doc', '*.odt']
excludes = ['/home/paulo-freitas/Documents']
def _filter(paths):
for path in paths:
if os.path.isdir(path) and not path in excludes:
yield path
for pattern in (includes + excludes):
if not os.path.isdir(path) and fnmatch.fnmatch(path, pattern):
yield path
for root, dirs, files in os.walk('/home/paulo-freitas'):
dirs[:] = _filter(map(lambda d: os.path.join(root, d), dirs))
files[:] = _filter(map(lambda f: os.path.join(root, f), files))
for filename in files:
filename = os.path.join(root, filename)
print(filename)
有更好的方法吗?如何?为什么要匹配
import os
excludes=....
for ROOT,DIR,FILES in os.walk("/path"):
for file in FILES:
if file.endswith(('doc','odt')):
print file
for directory in DIR:
if not directory in excludes :
print directory
没有经过彻底测试这里有一种方法可以做到这一点
import fnmatch
import os
excludes = ['/home/paulo-freitas/Documents']
matches = []
for path, dirs, files in os.walk(os.getcwd()):
for eachpath in excludes:
if eachpath in path:
continue
else:
for result in [os.path.abspath(os.path.join(path, filename)) for
filename in files if fnmatch.fnmatch(filename,'*.doc') or fnmatch.fnmatch(filename,'*.odt')]:
matches.append(result)
print matches
发件人:
walk(top[,top-down=True[,onerror=None[,followlinks=False]])
当topdown为True时,调用者可以就地修改dirnames列表…这可用于删除搜索
我应该指出,上面的代码假设
排除
是一种模式,而不是完整路径。如果os.path.join(root,d)不在excludes中,则需要调整列表理解以过滤以匹配OP大小写。此解决方案使用fnmatch.translate
将全局模式转换为正则表达式(它假定include仅用于文件):
非常适合您的用例:
from dirtools import Dir
print(Dir('.', exclude_file='.gitignore').files())
这是一个使用os.walk()
排除目录和文件的示例:
python>=3.2由于在makedirs
中存在ok
,上述方法对我不起作用
所以,这是我对我的原始答案的扩展
对我起作用的是:
if(not(str(root)+'/')。startswith(tuple(exclude_foldr)))
它编译了一个路径并排除了我列出的文件夹的元组
这给了我想要的确切结果
我的目标是让我的mac电脑井然有序
我可以通过路径搜索任何文件夹,定位并移动特定的文件。键入,忽略子文件夹,如果用户想移动文件,我会先提示用户
注意:提示符
每次运行仅一次,而不是每个文件
默认情况下,当您按enter键而不是[y/N]时,提示默认为NO
,并且只列出要移动的潜在的文件
这只是一个请访问的总脚本
提示:阅读下面的脚本,因为我在每行中添加了关于我所做工作的信息
从终端运行我的脚本的示例:
$ python3 organize_files.py
Exclude list: {'/Users/jkirchoff/Pictures/Archive', '/Users/jkirchoff/Documents/Stupid_Folder', '/Users/jkirchoff/Documents/Random', '/Users/jkirchoff/Documents/GitHub'}
Files found will be moved to this folder:/Users/jkirchoff/Pictures/Archive
Would you like to move files?
No? This will just list the files.
Yes? This will Move your files to the target folder.
[y/N]:
列出文件的示例:
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
...etc
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
To: /Users/jkirchoff/Pictures/Archive/1.custom-award-768x512.jpg
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
To: /Users/jkirchoff/Pictures/Archive/10351458_318162838331056_9023492155204267542_n.jpg
...
移动文件的示例:
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
...etc
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
To: /Users/jkirchoff/Pictures/Archive/1.custom-award-768x512.jpg
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
To: /Users/jkirchoff/Pictures/Archive/10351458_318162838331056_9023492155204267542_n.jpg
...
endswith应该是.doc和.odt。因为上面的代码中会返回一个名为mydoc[没有文件扩展名]的文件。此外,我认为这将符合OP发布的具体案例。排除可能也包含文件,而inclide可能包含dir。如果必须使用glob模式,则需要fnmatch
。@Oben Sonne,glob(IMO)比fnmatch具有更多的“功能”。例如,路径名扩展。您可以这样做,例如glob.glob(“/path/*/*/*/*.txt”)
。这一点很好。对于简单的include/exclude模式glob.glob()
可能是更好的解决方案。出于良好的实践和简化调试,我尽量不使用与内置类型匹配的变量名,例如您使用的“file”,因为这是一种内置类型。有一个输入错误:filename.odt
应该是`filename,如果include模式的数量增加,'*.odt'将不切实际。另外,不允许对要排除的目录名使用glob模式。Oben更正了错误。我同意包含模式部分。它可以在更通用的地方进行编码。如果在“if eachpath in path”下继续这样做是否是一个中断?呃,我们需要在两个re.match(excludes…)中检查if excludes
,否?如果排除=[]
,它将匹配所有条目。但我喜欢你的方法,更为清晰@你说得对,我没有考虑那个案子。因此,您可以1)将排除列表包装在if exclude
中,2)前缀不与not exclude或重新匹配(excludes…)
,或者3)如果原始排除为空,则将excludes设置为从不匹配的正则表达式。我使用变体3更新了我的答案。在谷歌搜索之后,[:]语法dirs[:]=[os.path.join(root,d)for d in dirs]
的要点似乎是使用变异切片方法,它改变了列表的位置,而不是创建一个新的列表。这让我抓狂——没有[:],它就不起作用。我仍然不懂力学,dirs[:]如何改变原始列表?所有手册都说,slice[:]返回列表的新副本,成员作为指向原始列表值的指针。那么dirs[:]如何改变原始列表呢?@Daniel:Slicing不仅可以用来获取列表的值,还可以用来分配选定的项目。由于[:]
表示完整的列表,因此分配给此片段将替换列表中以前的全部内容。请参阅。排除的
和包含的
在这里是什么样子的?有没有一个例子可以说明这个答案?
$ python3 organize_files.py
Exclude list: {'/Users/jkirchoff/Pictures/Archive', '/Users/jkirchoff/Documents/Stupid_Folder', '/Users/jkirchoff/Documents/Random', '/Users/jkirchoff/Documents/GitHub'}
Files found will be moved to this folder:/Users/jkirchoff/Pictures/Archive
Would you like to move files?
No? This will just list the files.
Yes? This will Move your files to the target folder.
[y/N]:
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
Files To Move: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
...etc
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/1.custom-award-768x512.jpg
To: /Users/jkirchoff/Pictures/Archive/1.custom-award-768x512.jpg
Moving File: /Users/jkirchoff/Documents/Archive/JayWork/10351458_318162838331056_9023492155204267542_n.jpg
To: /Users/jkirchoff/Pictures/Archive/10351458_318162838331056_9023492155204267542_n.jpg
...