Каков наилучший способ найти и заменить несколько запросов к нескольким файлам? - PullRequest
2 голосов
/ 09 августа 2011

У меня есть файл, который имеет более 200 строк в этом формате:

name old_id new_id

Имя бесполезно для того, что я сейчас пытаюсь сделать, но я все еще хочу его там, потому что оно может пригодиться для отладки позже.

Теперь мне нужно просмотреть каждый файл в папке, найти все экземпляры old_id и заменить их на new_id. Файлы, которые я сканирую, представляют собой файлы кода, длина которых может составлять тысячи строк. Мне нужно сканировать каждый файл с каждым из 200+ идентификаторов, которые у меня есть, потому что некоторые из них могут использоваться более чем в одном файле и несколько раз для каждого файла.

Каков наилучший способ сделать это? До сих пор я создавал скрипты Python, чтобы выяснить список старых и новых идентификаторов, и какие из них совпадают друг с другом, но я делал это очень неэффективно, потому что я в основном сканировал первый файл строка за строкой и получил текущий идентификатор текущей строки, затем я буду сканировать второй файл построчно, пока не найду совпадение. Затем я сделал это снова для каждой строки в первом файле, что закончилось тем, что я много читал второй файл. Я не возражал делать это неэффективно, потому что это были маленькие файлы.

Теперь, когда я ищу где-то около 30-50 файлов, которые могут содержать тысячи строк кода, я хочу, чтобы он был немного более эффективным. Это просто проект для любителей, поэтому он не должен быть супер хорошим, я просто не хочу, чтобы он занимал более 5 минут, чтобы найти и заменить все, а затем посмотреть на результат и увидеть, что я допустил небольшую ошибку и нужно сделать это снова и снова. Потратить несколько минут - это хорошо (хотя я уверен, что с компьютерами в настоящее время они могут сделать это почти мгновенно), но я просто не хочу, чтобы это было смешно.

Так, каков наилучший способ сделать это? До сих пор я использовал Python, но это не обязательно должен быть скрипт Python. Меня не волнует элегантность в коде или способ, которым я это делаю или что-то в этом роде, я просто хочу простой способ заменить все мои старые идентификаторы новыми идентификаторами, используя любой инструмент, который проще всего использовать или реализовать.

Примеры:

Вот строка из списка идентификаторов. Первая часть - это имя, которое можно игнорировать, вторая часть - старый идентификатор, а третья часть - новый идентификатор, который должен заменить старый идентификатор.

unlock_music_play_grid_thumb_01 0x108043c 0x10804f0

Вот пример строки в одном из файлов, подлежащих замене:

const v1, 0x108043c

Мне нужно иметь возможность заменить этот идентификатор новым идентификатором, чтобы он выглядел следующим образом:

const v1, 0x10804f0

1 Ответ

2 голосов
/ 09 августа 2011

Используйте что-то вроде multiwordReplace (я редактировал это для вашей ситуации) с mmap.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...