2017-02-11 14 views
0
  1. У меня есть список, содержащий некоторые строки.
  2. У меня есть набор файлов, которые могут содержать или не содержать эти строки.
  3. Мне нужно заменить эти строки на модифицированную версию строки в каждом экземпляре файлов. (например, string1_abc ->string1_xyz, string2_abc ->string2_xyz). По сути, подстрока, которая должна быть заменена и/или изменена, является общей для всех элементов в списке.

Есть ли какой-либо оптимизированный или простой способ сделать это? Самый наивный алгоритм, который я могу придумать, смотрит на каждую строку в каждом файле и для каждой строки, перебирает каждый из элементов в списке и заменяет это с помощью line.replace. Я знаю, что это дало бы мне O (MNQ) сложность где m = number of files, n = number of lines per file и q = number of items in the listСамый оптимизированный способ заменить строку в наборе файлов из списка

Примечание:

  1. Все размеры файлов не очень большой, так что я не уверен, что чтение строки по строка vs делает file.read() в буфер лучше?
  2. q также не очень большой. Список составляет около 40-50 наименований.
  3. m довольно большой.
  4. n может идти до 5000 строк.

Кроме того, я играл с Python на стороне и не очень привык к нему. Кроме того, я ограничен в использовании Python 2.6

+0

Есть ли вероятность того, что ваша целевая строка перейдет в разрыв строки? т. е. 'string1_abc == stri \ nng1_abc' для этой цели? – dawg

+0

Использование выражения генератора может быть лучше – Viney

+0

Регулярное выражение может более эффективно выполнять совпадение (т. Е. Один проход). Захватите матч и используйте его, чтобы посмотреть, какую замену вам нужно сделать. – pvg

ответ

0

Псевдо Python:

import glob 
LoT=[("string1_abc","string1_xyz"), ("string2_abc","string2_xyz")] 
for fn in glob.glob(glob_describes_your_files): 
    with open(fn) as f_in: 
     buf=f_in.read() # You said n is about 5000 lines so 
          #  I would just read it in 
     for t in LoT: 
      buf=buf.replace(*t) 
    # write buf back out to a new file or the existing one 
    with open(fn, "w") as f_out: 
     f_out.write(buf) 

Что-то вроде этого ...


Если файлы BIG, исследуют с помощью mmap на файлах и все остальное более или менее одинаково.

+0

Не использовали mmap, но он похоже использование .read кажется проще. И я не уверен, какая разница, но это число составляет около 5000 строк, а не 500. – umayneverknow

+0

Если в файлах 5000 строк, скажем, 80 символов в строке, вы говорите о 400 кбайтах. В зависимости от среды (Pi? Desktop? Phone?) Да, я бы просто использовал '.read()', так как в противном случае вам нужно будет запустить цикл, чтобы заменить его еще много раз. – dawg

+0

Имеет смысл. Благодаря! – umayneverknow