» Замена фразы в текстовом файле

K.A.V.
www.oszone.net
22.02.2010
Автор: K.A.V.
Последнее обновление: 9.08.2012

На этой страничке я приведу пример кода, который позволит вам выполнить поиск фразы в файле и выполнить замену данной фразы во всех строках в файле на необходимую, либо произвести замену 1 раз и завершить функцию (как сделать одноразовую замену, читайте коммент выделенный красным цветом)

В начале кода:
!include "StrFunc.nsh"
!include "WinMessages.nsh"
${StrRep}

Вариант функции №1

Функция поиска и замены фразы в текстовом файле (с показом прогресса):
Function ReplaceLinesInFile
  Banner::show /NOUNLOAD ""
  Banner::getWindow /NOUNLOAD
        Pop $1
     GetDlgItem $2 $1 1030
; Создаём баннер, чтобы видеть прогресс (для наглядности)

Var /Global _FindInFile ; В эту переменную поместим полный путь к файлу, в котором будем производить замену
Var /Global _LineReplace ; В эту переменную поместим строку, которую будем искать и заменять
Var /Global _LineToInsert ; В эту переменную поместим строку, НА которую мы будем заменять искомую строку
Var /Global _CurLineNumber ; В этой переменной храним номер обрабатываемой строки
Var /Global _CurLine ; В этой переменной храним строку, с которой в данный момент сверяем
Var /Global _LineNumbers ; В этой переменной храним количество строк в искомом файле

StrCpy $_FindInFile '$EXEDIR\TEST.txt' ; Заменяем строки в этом файле
StrCpy $_LineReplace 'NSIS' ; Ищем и заменяем ЭТУ фразу
StrCpy $_LineToInsert 'Справочник по NSIS' ; На что будем заменять

${LineSum} "$_FindInFile" $_LineNumbers ; Подсчитываем количество строк
strcpy $_CurLineNumber 0
startLineRead:
intop $_CurLineNumber $_CurLineNumber + 1

     SendMessage $2 ${WM_SETTEXT} 0 "STR:Обработка строки $_CurLineNumber [Всего: $_LineNumbers]" ; Смотрим прогресс обработки строк =)

IntCmp $_CurLineNumber $_LineNumbers 0 0 endFunc ; Если номер текущей строки больше количества строк в файле - поиск завершен

${LineRead} "$_FindInFile" "$_CurLineNumber" $_CurLine ; Читаем строку по номеру текущей строки
${WordFind} '$_CurLine' "$_LineReplace" "E+1{" $R0 ; Ищем в строке нужный текст

StrCmp $R0 "1" startLineRead 0 ; Если в строке присутствует искомый текст, выполняем код ниже
${LineFind} "$_FindInFile" "" "" "Insert_Line" ; Вызываем функцию Insert_Line, которая произведёт замену
goto startLineRead
; Если хотите, чтобы после первой же замены скрипт больше не читал файл (замена одного значения) - удалите строку выше
endFunc:

  Banner::destroy ; Уничтожаем баннер
FunctionEnd


Function Insert_Line
StrCmp $R8 "$_CurLineNumber" 0 push
        ${StrRep} $_CurLine "$_CurLine" "$_LineReplace" "$_LineToInsert"
    FileWrite $R4 "$_CurLine"
    StrCpy $0 SkipWrite
    push:
    Push $0
FunctionEnd


Вариант функции №2 (можно выполнить несколько раз + более удобный вид + без баннера)

В начале кода:
Var _FindInFile ; В эту переменную поместим полный путь к файлу, в котором будем производить замену
Var _LineReplace ; В эту переменную поместим строку, которую будем искать и заменять
Var _LineToInsert ; В эту переменную поместим строку, НА которую мы будем заменять искомую строку
Var _CurLineNumber ; В этой переменной храним номер обрабатываемой строки
Var _CurLine ; В этой переменной храним строку, с которой в данный момент сверяем
Var _LineNumbers ; В этой переменной храним количество строк в искомом файле

!include "StrFunc.nsh"
${StrRep}

В данном варианте этой же функции, вам необходимо в любом месте вашего скрипта сначала назначить переменным данные, а затем вызвать функцию ReplaceLinesInFile
Section /o "Моя секция"
StrCpy $_FindInFile '$EXEDIR\TEST.txt' ; Заменяем строки в этом файле
StrCpy $_LineReplace 'NSIS' ; Ищем и заменяем ЭТУ фразу
StrCpy $_LineToInsert 'Справочник по NSIS' ; На что будем заменять
call ReplaceLinesInFile
SectionEnd

Function ReplaceLinesInFile
${LineSum} "$_FindInFile" $_LineNumbers ; Подсчитываем количество строк
strcpy $_CurLineNumber 0
startLineRead:
intop $_CurLineNumber $_CurLineNumber + 1
IntCmp $_CurLineNumber $_LineNumbers 0 0 endFunc ; Если номер текущей строки больше количества строк в файле - поиск завершен
${LineRead} "$_FindInFile" "$_CurLineNumber" $_CurLine ; Читаем строку по номеру текущей строки
${WordFind} '$_CurLine' "$_LineReplace" "E+1{" $R0 ; Ищем в строке нужный текст
StrCmp $R0 "1" startLineRead 0 ; Если в строке присутствует искомый текст, выполняем код ниже
${LineFind} "$_FindInFile" "" "" "Insert_Line" ; Вызываем функцию Insert_Line, которая произведёт замену
goto startLineRead
; Если хотите, чтобы после первой же замены скрипт больше не читал файл (замена одного значения) - удалите строку выше

endFunc:
FunctionEnd

Function Insert_Line
StrCmp $R8 "$_CurLineNumber" 0 push
        ${StrRep} $_CurLine "$_CurLine" "$_LineReplace" "$_LineToInsert"
    FileWrite $R4 "$_CurLine"
    StrCpy $0 SkipWrite
    push:
    Push $0
FunctionEnd