Page 1 of 1

Search and replace a line in a text file

Posted: Tue Sep 08, 2009 9:49 pm
by Little John
Works also with PB 5.20

Hi all,

because there was demand for it, here is a small procedure that searches and replaces one line in a text file.
Note: newText$ may contain #CR$, #LF$ or #CRLF$ -- i.e. it may consist of more than one line.

Regards, Little John

Code: Select all

; PB 4.31

EnableExplicit

Procedure.i ReplaceLine (file$, lineBeg$, newText$, caseSensitive=#True)
   ; in : file$        : name of text file, in which a line is to be replaced
   ;      lineBeg$     : begin of the regarding line
   ;      newText$     : text that will replace the regarding line
   ;      caseSensitive: search mode (#True or #False)
   ; out:     1: successful replacement,
   ;          0: lineBeg$ not found,
   ;      <= -1: error
   Protected fn, *buffer, line$
   Protected lineOffset.q, bufferSize.q

   ; open existing file
   If FileSize(file$) = -1
      ProcedureReturn -1             ; error
   EndIf
   fn = OpenFile(#PB_Any, file$)
   If fn = 0
      ProcedureReturn -1             ; error
   EndIf

   ; look for regarding line
   If caseSensitive = #False
      lineBeg$ = UCase(lineBeg$)
   EndIf
   Repeat
      lineOffset = Loc(fn)
      line$ = ReadString(fn)
      If caseSensitive = #False
         line$ = UCase(line$)
      EndIf
      If FindString(line$, lineBeg$, 1) = 1
         Break                       ; found
      EndIf
      If Eof(fn)
         CloseFile(fn)
         ProcedureReturn 0           ; not found
      EndIf
   ForEver

   ; save last part of the file
   ; (everything behind the regarding line)
   bufferSize = Lof(fn) - Loc(fn)
   *buffer = AllocateMemory(bufferSize)
   If ReadData(fn, *buffer, bufferSize) <> bufferSize
      FreeMemory(*buffer)
      CloseFile(fn)
      ProcedureReturn -2             ; error
   EndIf

   ; write new text at proper position
   FileSeek(fn, lineOffset)
   WriteStringN(fn, newText$)

   ; re-write last part of the file
   WriteData(fn, *buffer, bufferSize)
   TruncateFile(fn)
   FreeMemory(*buffer)
   CloseFile(fn)

   ProcedureReturn 1                 ; success
EndProcedure


;-- Demo
Define file$, lineBeg$, newText$

file$ = "prefs.js"    ; Firefox
lineBeg$ = "user_pref(" + Chr(34) + "browser.startup.homepage"
newText$ = "user_pref(" + Chr(34) + "browser.startup.homepage" + Chr(34) + ", " + Chr(34) + "http://www.yan.ru/" + Chr(34) + ");"

Debug ReplaceLine(file$, lineBeg$, newText$)  ; shows 1 on success