【问题标题】:What is the best way to do a find and replace of multiple queries on multiple files?在多个文件上查找和替换多个查询的最佳方法是什么?
【发布时间】:2011-10-22 23:33:07
【问题描述】:

我有一个超过 200 行的文件:

name old_id new_id

这个名字对于我目前正在尝试做的事情没有用,但我仍然想要它,因为它可能对以后的调试有用。

现在我需要遍历文件夹中的每个文件并找到 old_id 的所有实例并将它们替换为 new_id。我正在扫描的文件是可能长达数千行的代码文件。我需要使用我拥有的 200 多个 id 中的每一个扫描每个文件,因为有些文件可能用于多个文件,并且每个文件多次使用。

执行此操作的最佳方法是什么?到目前为止,我一直在创建 python 脚本来找出旧 id 和新 id 的列表以及哪些是相互匹配的,但是我这样做效率很低,因为我基本上是逐行扫描第一个文件并得到当前行的当前 id,然后我将逐行扫描第二个文件,直到找到匹配项。然后我对第一个文件中的每一行都重复了一遍,最后我读了很多第二个文件。我不介意这样做效率低下,因为它们是小文件。

现在我可能正在搜索大约 30-50 个文件,其中可能包含数千行代码,我希望它更高效一些。这只是一个爱好者项目,所以它不需要超级好,我只是不希望它花费超过 5 分钟的时间来查找和替换所有内容,然后查看结果,发现我犯了一个小错误并且需要重新做一遍。花几分钟就可以了(尽管我确信现在的计算机仍然可以立即执行此操作),但我只是不想让它变得荒谬。

那么最好的方法是什么?到目前为止,我一直在使用 python,但它不需要是 python 脚本。我不关心代码的优雅或我做它的方式或任何东西,我只想要一种简单的方法,使用最容易使用或实现的任何工具,用我的新 id 替换所有旧 id。

示例:

这是 id 列表中的一行。第一部分是名称,可以忽略,第二部分是旧id,第三部分是需要替换旧id的新id。

unlock_music_play_grid_thumb_01 0x108043c 0x10804f0

这是要替换的文件之一中的示例行:

const v1, 0x108043c

我需要能够用新的 id 替换那个 id,所以它看起来像这样:

const v1, 0x10804f0

【问题讨论】:

  • 您能否也从代码文件中添加一些示例行以了解我们要替换的内容?

标签: python regex performance search replace


【解决方案1】:

mmap 中使用multiwordReplace 之类的内容(我已根据您的情况对其进行了编辑)。

import os
import os.path
import re
from mmap import mmap
from contextlib import closing


id_filename = 'path/to/id/file'
directory_name = 'directory/to/replace/in'

# read the ids into a dictionary mapping old to new
with open(id_filename) as id_file:
    ids = dict(line.split()[1:] for line in id_file)    

# compile a regex to do the replacement
id_regex = re.compile('|'.join(map(re.escape, ids)))

def translate(match):
    return ids[match.group(0)]

def multiwordReplace(text):
    return id_regex.sub(translate, text)

for code_filename in os.listdir(directory_name):
    with open(os.path.join(directory, code_filename), 'r+') as code_file:
        with closing(mmap(code_file.fileno(), 0)) as code_map:
            new_file = multiword_replace(code_map)
    with open(os.path.join(directory, code_filename), 'w') as code_file:
        code_file.write(new_file)

【讨论】:

  • 感谢您的代码,但是我在运行它时遇到了错误。 中的文件“./multreplace.py”,第 29 行,关闭(mmap(code_file.fileno(),0))作为 code_map:mmap.error:[Errno 13] 权限被拒绝。我是该文件的所有者,并且能够对其进行编辑,因此我不确定为什么会收到此文件。
  • @lemons 我的错,你需要以r+ 模式打开文件以获得可写的mmap。我会编辑。
  • 嗯,好的。所以现在脚本运行了,但没有任何修改。我已经将脚本、id 文件和文件夹以及所有要更改的文件都放在同一个目录中,并且在脚本运行没有错误之后,什么都没有改变。我在做之前备份了文件夹,并对两个文件夹进行了比较,它们仍然完全相同。
  • @lemons 呵呵,我以为multilineReplace 函数改变了文本;它没有。固定。
  • 太棒了,现在可以了!你介意解释一下那里到底发生了什么吗?我从来没有使用过 mmap,而且我对正则表达式还是新手,所以这个脚本对我来说有点混乱。我想知道它是如何工作的,所以下次我可以自己做:)
猜你喜欢
  • 2010-10-06
  • 2020-07-17
  • 2010-09-11
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多