2

我需要一个类似于 GLOB2FORMIC的解决方案来搜索文本文件中的大量目录列表(文件不在我的机器上,文件列表是由我无法直接访问或查询的外部进程生成的)

伪示例:

# read the large directory list in memory
data = []
with open('C:\\log_file.txt','r') as log:
    data = log.readlines()

# query away!
query1 = listglob(data,'/**/fnord/*/log.*')
query2 = listglob(data,'/usr/*/model_*/fnord/**')

除非有人有建议,否则我的下一步是打开 glob2 和 formic,看看是否可以将其中一个更改为接受列表而不是根文件夹以成为“os.walked”

4

3 回答 3

2

我建议使用正则表达式。最终,Formic 和glob使用操作系统调用来执行实际的全局匹配。因此,如果您想修改其中任何一个,无论如何您都必须编写一个 RE 匹配器(或类似的)。所以,去掉中间人,直接去 REs。(这么说让我很痛苦,因为我是 Formic 的作者)。

基本计划是编写一个接收 glob 并返回正则表达式的函数。这里有一些提示:

  1. 转义和.,-以及 glob 中的其他 RE 保留字符。例如.变成\.
  2. glob 文件/目录中的A?变为[^/](匹配不是 a 的单个字符/
  3. *作为正则表达式的 glob 文件/目录名称中的A是[^/]*
  4. /*/作为正则表达式的glob 是:/[^/]+/
  5. /**/作为正则表达式的glob 是:/([^/]+/)*
  6. 要匹配整行,请以 a 开头^并以 . 结尾$。这迫使 RE 扩展到整个字符串。

虽然我按照复杂性增加的顺序列出了替换,但按以下顺序进行替换可能是个好主意:

  1. 不是 glob 的特殊 RE 字符(., -, '$' 等)
  2. ?
  3. /**/
  4. /*/
  5. *

这样你就不会/**/在替换单个*.

在您的问题中,您有:/**/fnord/*/log.*。这将映射到:

^/([^/]+/)*fnord/[^/]+/log\.[^/]*

一旦你建立了你的 RE,然后寻找匹配是一个简单的练习。

于 2013-11-15T01:06:14.607 回答
1

最后,我使用了 glob2 的一个功能,如下所示:

import glob2

def listglob(data,pattern):
    return [x for x in items if glob2.fnmatch.fnmatch(x,pattern)]
于 2013-11-28T00:17:47.447 回答
0

我认为这不glob2.fnmatch.fnmatch等同于glob2 **语法。

它相当于fnmatch我从阅读源代码中可以看出的语法。

安德鲁的回答也不包括方括号。和[!abc]例子

于 2015-09-23T03:48:28.703 回答