ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python,如何实现类似.gitignore行为的东西

2019-10-01 11:55:09  阅读:297  来源: 互联网

标签:python pattern-matching glob gitignore fnmatch


我需要列出当前目录(.)中的所有文件(包括所有子目录),并排除一些文件,如.gitignore如何工作(http://git-scm.com/docs/gitignore)

使用fnmatch(https://docs.python.org/2/library/fnmatch.html),我将能够使用模式“过滤”文件

ignore_files = ['*.jpg', 'foo/', 'bar/hello*']
matches = []
for root, dirnames, filenames in os.walk('.'):
  for filename in fnmatch.filter(filenames, '*'):
      matches.append(os.path.join(root, filename))

如何“过滤”并获取与“ignore_files”的一个或多个元素不匹配的所有文件?

谢谢!

解决方法:

你走在正确的轨道上:如果你想使用fnmatch风格的模式,你应该使用fnmatch.filter.

但是有三个问题使得这不是微不足道的.

首先,您想要应用多个过滤器.你是怎样做的?多次呼叫过滤:

for ignore in ignore_files:
    filenames = fnmatch.filter(filenames, ignore)

其次,您实际上想要执行与过滤器相反的操作:返回不匹配的名称子集.正如文档所述:

It is the same as [n for n in names if fnmatch(n, pattern)], but implemented more efficiently.

所以,要做相反的事情,你只需要投入一个:

for ignore in ignore_files:
    filenames = [n for n in filenames if not fnmatch(n, ignore)]

最后,您尝试过滤部分路径名,而不仅仅是文件名,但是在过滤之后才进行连接.所以切换顺序:

filenames = [os.path.join(root, filename) for filename in filenames]
for ignore in ignore_files:
    filenames = [n for n in filenames if not fnmatch(n, ignore)]
matches.extend(filenames)

有几种方法可以改善这一点.

您可能希望使用生成器表达式而不是列表推导(括号而不是方括号),因此如果您有大量文件名列表,则使用惰性管道而不是浪费时间和空间重复构建大型列表.

此外,如果颠倒循环的顺序,它可能会或可能不会更容易理解,如下所示:

filenames = (n for n in filenames 
             if not any(fnmatch(n, ignore) for ignore in ignore_files))

最后,如果您担心性能,可以在每个表达式上使用fnmatch.translate将它们转换为等效的regexp,然后将它们合并为一个大的正则表达式并编译它,并使用它而不是围绕fnmatch的循环.如果允许你的模式比* .jpg更复杂,这可能会变得棘手,除非你确实在这里确定了性能瓶颈,否则我不会推荐它.但是如果你需要这样做的话,我至少看过一个关于SO的问题,有人花了很多精力来解决所有边缘情况,所以搜索而不是试图自己编写.

标签:python,pattern-matching,glob,gitignore,fnmatch
来源: https://codeday.me/bug/20191001/1838860.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有