2013-05-29 2 views
2

Я пытался уложить свой мозг в течение нескольких часов на этом.Как вставить текст в строку после последнего появления строки поиска?

Я пытаюсь написать сценарий, который добавит дополнительный файл include и комментарий после последнего появления существующего файла include в наборе исходных файлов * .cpp. Исходные файлы находятся в рекурсивном наборе каталогов, поэтому я полагаю, что мой прерыватель должен начинаться с поиска.

Например, раньше:

#include <a> 
#include <b> 
#include <c> 
// source code... 

После:

#include <a> 
#include <b> 
#include <c> 
// This is the extra include file 
#include <d> 
// source code... 

ответ

0

Вы можете сделать это в Python, я сделал пример ниже сценарий:

import os 

def find_last_include(file_name): 
    """ Returns last line with an include statement at the start """ 
    last_include_line = 0 
    with open(file_name, "r") as f: 
     for i,line in enumerate(f): 
      if line.strip().startswith("#include"): 
       last_include_line = max(i, last_include_line) 
    return last_include_line 



def insert_line(file_name, last_include_line_no, new_line): 
    """ New line should end with \n""" 
    try: 
     with open(file_name,"r+") as f: 
      print "Opening: {0}".format(file_name) 
      # File is all the lines in the file as a list 
      file = f.readlines() 
      # last include line is the line we are going to replace the last inculde 
      # with the last include + the new line we want 
      last_include_line = file[last_include_line_no] + new_line 
      file[last_include_line_no] = last_include_line 
      print "Inserting: '{0}' On line: {1}".format(new_line.strip(), last_include_line_no) 
      f.seek(0) # Seek back to the start of the file 
      for line in file: 
       f.write(line) # Write the lines with changes to the file 
    except IOError as e: 
     print e 
    return None 


if __name__ == '__main__': 
    c_files = find_all(".c","Y:\\Python Stuff") 
    line = "#include <c>\n" 
    for c_file in c_files: 
     insert_line(c_file, find_last_include(c_file), line) 
    print "Finished Inserting lines" 

Печатается:

SEARCHING FOR FILES.. 
FOUND FILE: Y:\Python Stuff\prog.c 
Finished finding 
Opening: Y:\Python Stuff\prog.c 
Inserting: #include <c> On line: 34 
Finished Inserting lines 

Что это делает, найти все файлы «.c», начиная из заданной папки, затем находит, в какую строку включен последний включитель, и добавляет строку к этой строке и перезаписывает файл. Работает как шарм. Однако любые комментарии к улучшению будут оценены.

+0

Я думаю, что вопрос подразумевает, что он не знает, что такое , и просто хочет найти последнюю строку #include в файле. Ему нужно будет прочитать весь файл, а затем вернуться и добавить новые строки, как только он узнает, где на самом деле находится последний. –

+0

oo мог бы сделать это, нужно будет переосмыслить мой страт – Noelkd

+0

@noelkd: Да, #include указывает включение любого файла, либо внутри угловых скобок, либо кавычек. Спасибо всем тем же. – Paul

1

Ваш вопрос довольно расплывчатым. Поэтому я расстаюсь с тем, что вам нужно сделать.

  1. Найти, где заканчиваются включения (регулярное выражение, функция, написанная вручную).
  2. Разделить исходный текст на две части.
  3. head + your include + tail = новый текст.
  4. напишите новый текст во временном файле.
  5. удалить старый файл.
  6. переименуйте файл temp в старое имя файла.

Вы можете использовать C++ для этого, а boost (а также C++ 11) содержит все необходимые абстракции.

0

Как я уверен, вы уже обнаружили, что трудная часть этой проблемы - «после последнего появления». Это напоминает мне моего дедушку, который живет 87 лет в одном городе и иногда дает указания типа «мы всего лишь блок мимо последней бензоколонки на главной улице», Если бы вы не знали Main St. достаточно хорошо, чтобы знать, что последняя станция была 76, вы могли бы оказаться в следующем городе, думая, есть ли еще еще одна бензоколонка.

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

Есть, я считаю, способы сделать это в потоковой усадьбе, но они все равно потребуют двух проходов через ваши данные. С другой стороны, это явно файл исходного кода, который означает, что он достаточно мал и легко вписывается в память.

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

+0

Угловой футляр, который вы описываете, я бы даже не угодил. Это означает, что никаких соглашений о кодировании не существует. –