Я изучаю изменение имени файла сотен файлов в (C/C++) проект, что я продолжаю работать. Проблемой является наше программное обеспечение, имеет десятки тысяч файлов, что включая (т.е. #include) эти сотни файлов, которые будут изменены. Это похоже на кошмар обслуживания. Если я сделаю это, то я буду застревать в Ультраредактировании в течение многих недель, прокручивая сотни regex's вручную как так:
^\#include.*["<\\/]stupid_name.*$
с
#include <dir/new_name.h>
Такая тяжелая работа была бы хуже, чем очищение сотен картофеля в затонувшей подводной лодке в Антарктике с ложкой. Я думаю, что это было бы идеально для помещения вводов и выводов в таблицу как так:
stupid_name.h <-> <dir/new_name.h>
stupid_nameb.h <-> <dir/new_nameb.h>
stupid_namec.h <-> <dir/new_namec.h>
и подайте это в механизм регулярного выражения / инструмент / приложение / и т.д...
Мой Окончательный Вопрос: существует ли инструмент, который сделает это?
Вопрос о премии: действительно ли это является многопоточным?
Я посмотрел, довольно многие ищут и заменяют темы здесь на этом веб-сайте и нашли много стандартных запросов, которые спросили вариант следующего вопроса:
стандартный вопрос: Замените один термин в файлах N.
в противоположность:
мой вопрос: Замените условия N в файлах N.
Заранее спасибо за любые ответы.
Как говорит Марк Уилкинс, это работоспособный план с любым удобным инструментом для создания сценариев с регулярными выражениями, который вы предпочитаете, но я бы предложил пару дополнительных моментов:
PowerGREP может это сделать. Он может искать несколько строк поиска (буквальный текст или регулярные выражения) в любой комбинации файлов и является многопоточным (начиная с PowerGREP 4, текущей версии).
альтернативный текст http://img682.imageshack.us/img682/5172/screen006c.png
Вы можете сохранить результаты поиска для последующего повторного использования.
Я думаю, что ваш Идея размещения старых / новых имен в одном месте - хорошая.Это, безусловно, уменьшит сложность поддержания и проверки изменений. Кажется, что это очевидный ответ, но я думаю, что использование любого из популярных языков сценариев, таких как ruby, python, perl и т. Д., Сделает эту задачу довольно простой. Сценарий может прочитать файл, содержащий старую / новую информацию о замене, построить из нее соответствующие регулярные выражения, а затем обработать файлы, которые нуждаются в замене.
Сценарий можно было бы написать как многопоточную утилиту, хотя не похоже, что в такой ситуации будет много пользы. Если я понимаю вопрос, это должно быть в основном одноразовое использование, поэтому высокая производительность не кажется главным приоритетом.
Создайте серию однострочных файлов perl для редактирования файлов на месте, например:
perl -i.bak -p -e 's/stupid_old_name/cool_new_name/' *.c
Это дает дополнительный бонус в виде сохранения оригиналов любых измененных файлов с расширением .bak.
Я бы сделал кучу таких, если бы не знал Perl так хорошо. Я бы даже поместил все однострочные в сценарий оболочки, но тогда я не пытаюсь произвести впечатление на кого-либо из седобородых юниксов.
На этом веб-сайте очень хорошо объясняется редактирование на месте с помощью perl: http://www.rice.edu/web/perl-edit.html
PS - Поскольку я достаточно хорошо знаю Perl ну, я бы просто написал таблицу was / is в «реальном» perl-скрипте и использовал бы ее для открытия и анализа всех файлов.
Я бы использовал awk, инструмент командной строки, похожий на sed.
mv file.x file.x.bak;
awk '{
gsub( "#include \"bad_one.h\"" , "#include \"good_one.h\"" );
gsub( "#include \"bad_two.h\"" , "#include \"good_two.h\"" );
}' file.x.bak > file.x;
Когда вы окажетесь у терминала, используйте man awk
, чтобы увидеть более подробную информацию.
в * nix (или GNU win32), вы можете использовать GNU find и sed вместе ... например,
find /path -type f -name "*.c" -exec sed -i.bak 's/^\#include.*["<\\/]stupid_name.*$/#include <dir\/new_name.h>/' "{}" +;
объяснение,
команда find
начинает поиск файлов ( -тип f
), начиная с / path
. -name "* .c"
ищет все файлы .c
, затем для каждого найденного выполняет sed
, чтобы заменить строку на новую. -i.bak
просит sed
сохранить исходный файл в качестве резервной копии перед редактированием на месте. "{}"
означает файл, переданный в sed