SNR
Это небольшая консольная утилита для автоматической замены фрагментов строк в текстовых файлах. Не думал, что опять придется изобретать велосипед, но пришлось...
Понадобилось мне сделать простую, вроде бы, вещь: привести к общему виду все функции в HwGUI - поставить в названиях префикс "hwg_", ну и, соответственно, сделать автоматический search and replace - изменить во всех исходниках вызовы этих функций. Казалось бы, средств для этого более, чем достаточно. Любой текстовый редактор это делает, и утилит всяких для этого немало. Но, как часто бывает, при ближайшем рассмотрении выяснилось, что не все так просто, везде не хватает чего-то важного.
Что мне, собственно, надо:
- чтобы операция производилась автоматически с группой файлов, находящихся, возможно, во вложенных каталогах;
- чтобы можно было задать произвольное количество пар найти/заменить, а не производить эту операцию для каждой пары отдельно;
- чтобы менялось именно то, что надо, например, строка cSelectFile := SelectFile( par1,... )
,была заменена на cSelectFile := hwg_SelectFile( par1,... )
, это обычно регулируется опцией "Whole words" - "Целые слова".
Я скачал несколько утилит по ссылкам с Яндекса и попробовал их. Некоторые пришлось устанавливать, что само по себе для такой простой программы выглядит странно и поэтому немного раздражает. Но везде чего-то не хватало, чаще всего пункта 2 моих требований. В одной из них, вроде, было все, что нужно, но она была shareware, а интерфейс был, мягко говоря, не очень удачный - у меня потребовало времени разобраться с ним и каким-то непонятным образом она произвела операцию поиска/замены над файлами, которые я не собирался трогать.
Наверное, я просто не проявил достаточно терпения, но, в конце концов, счел за лучшее написать такую утилиту самому. Потом, раз уж начал, добавил туда опций, которые не нужны для выполнения текущей задачи, но могут понадобиться позже - мне, или, может, кому другому.
Итак, Snr2, прошу любить и жаловать ( ссылка для скачивания, исходник и исполняемый файл ).
snr2 [-tTemplateName] | [-hheaderName] | [-sSearchString -iInsertString] [-r[+|-]] [-c[+|-]] [-w[+|-]] [-f[+|-]] [-a[+|-]] [-v[+|-]] [-b[ext]] mask-tTemplateName - указывает имя текстового файла (TemplateName), в котором построчно перечислены разделенные пробелами пары найти/заменить;
-hheaderName - указывает имя заголовочного файла (headerName) - подробнее об этом см. ниже;
-sSearchString - фрагмент, который надо найти;
-iInsertString - фрагмент, на который надо заменить найденную SearchString;
-r - рекурсивный поиск во вложенных каталогах, по умолчанию выключен;
-c - опция "Case sensitive", по умолчанию выключена;
-w - опция "Whole words" - "Целые слова", по умолчанию включена, чтобы выключить, используйте -w-;
-f - эта опция заменяет только имена функций (проверяет, следует ли за искомым словом круглая скобка), по умолчанию выключена;
-a - автоматическая замена, по умолчанию включена. Если эта опция выключена при помощи -a-, то перед каждой заменой на экран выводится изменяемый фрагмент и вопрос: заменить или нет, на который вы должны ответить нажатием клавиши Enter или "y" (да), или "n" - нет;
-v - более подробный журнал изменений, по умолчанию выключена;
-b[ext]. По умолчанию старый файл остается без изменений и создается новый файл с добавленным расширением .new. Если вы задаете опцию -b, старый файл сохраняется с указанным вами расширением ( ext, если вы его не указали, то расширение по умолчанию - orig ), а новый занимает его место;
mask - маска файлов, которые надо изменить, это может быть имя одного файла. Если вам надо использовать несколько масок, можно задать их через " ; ":
*.prg;*.ch
.
В командной строке надо указывать или -tTemplateName, или -hheaderName, или пару значений -sSearchString и -iInsertString. Если у вас одна пара значений для замены, например, SelectFile на hwg_SelectFile, то вы можете задать ее в командной строке:
snr2 -sSelectFile -ihwg_SelectFile *.prg
Если таких пар несколько, то вам надо создать текстовый файл вот такого вида:
SelectFile hwg_SelectFile SaveFile hwg_SaveFile Printersetup hwg_Printersetupи запустить snr2:
snr2 -tshablon.txt *.prgгде shablon.txt - имя этого файла.
Специально для Harbour-программистов: в качестве шаблона можно использовать заголовочный ( *.h, *.ch ) файл, где строки что на что изменить задаются с помощью директивы #xtranslate:
#xtranslate Selectfile([]) => hwg_Selectfile( )
Таким образом, чтобы заменить вызовы функций на новые во всех ваших исходных файлах, написанных на [x]Harbour+HwGUI, надо сделать следующее:
snr2 -hhwgcompat.ch -f -r *.prgпотому что именно в файле hwgcompat.ch собраны соответствущие директивы #xtranslate.
Еще пара слов о текстовых шаблонах, задаваемых опцией -t. Если вы меняете не названия функций, а произвольные строки с пробелами внутри, то соответствующую строку надо заключить в одинарные или двойные кавычки, например:
"do while .t." "DO WHILE TRUE"Это же касается и опций командной строки -s, -i:
snr2 -s"do while .t." -i"DO WHILE TRUE" *.prg
По окончании работы snr2 создается журнал snr2.log, в начале его перечислены пары найти/заменить и опции процесса, а затем список измененных файлов. Если была задана опция -v, то в журнал включаются фрагменты замененных строк.
Имеется и графический вариант этой утилиты - Fileagent