使用Ruby或Python在文件中查找

4 投票
2 回答
1486 浏览
提问于 2025-04-15 11:28

有一个很受欢迎的文本编辑器,它有一个“在文件中查找”的功能,这个功能会在一个对话框中打开:

 Look For:       __searchtext__
 File Filter:    *.txt; *.htm
 Start From:     c:/docs/2009
 Report:         [ ] Filenames [ ]FileCount only
 Method:         [ ] Regex     [ ]Plain Text

其实,很多流行的文本编辑器都有这个功能。

我想用Python或Ruby的类来实现同样的功能,而不是使用文本编辑器。这样的话,这种简单的操作就可以通过脚本在任何支持Ruby或Python的平台上运行。

问题: 我不想自己写这个,有没有人知道有没有Ruby或Python的脚本,可以接受相同或类似的简单输入参数,并且能完成你所期待的功能?

我想要的就是一种简单的线性搜索,不涉及索引搜索的内容。

2 个回答

3

Grepper是David A. Black开发的一个Ruby库,专门用来做这个事情:

g = Grepper.new
g.files = %w{ one.txt two.txt three.txt }
g.options = %w{ B2 }   # two lines of before-context
g.pattern = /__search_string__/
g.run

g.results.each do |file, result|
  result.matches.each do |lineno, before, line, after|
    etc....

我认为它会调用grep这个工具,并把结果包装成Ruby对象,这意味着它可以使用和grep一样的选项。安装方法是:

sudo gem install grepper
5

我知道你说你不想自己写这个,但其实用 os.walk 来做这件事非常简单,你可以这样写:

results = []
if regex_search:
    p = re.compile(__searchtext__)
for dir, subdirs, subfiles in os.walk('c:/docs/2009'):
    for name in fnmatch.filter(subfiles, '*.txt'):
        fn = os.path.join(dir, name)
        with open(fn, 'r') as f:
            if regex_search:
                results += [(fn,lineno) for lineno, line in enumerate(f) if p.search(line)]
            else:
                results += [(fn,lineno) for lineno, line in enumerate(f) if line.find(__searchtext__) >= 0]

(顺便说一下,这是Python语言)

撰写回答