Replace multiple patterns in file using callbacks: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
m (Added category links.) |
m ("Archive" -> "Wiki". Added link to AdvReplaceInFile.) |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
{ | {{PageAuthor|bazzargh}} | ||
== Description == | == Description == | ||
There's other versions of find and replace that allow you to find and replace a single string in a file, but they don't deal with multiple replacements on a single line, or replacements of multiple patterns. I've written an alternative that reads and writes a file, calling a supplied function for every line, so you can make that function do the multiple replacements; thus doing all your replacements in a single pass. | There's other versions of find and replace that allow you to find and replace a single string in a file, but they don't deal with multiple replacements on a single line, or replacements of multiple patterns. I've written an alternative that reads and writes a file, calling a supplied function for every line, so you can make that function do the multiple replacements; thus doing all your replacements in a single pass. | ||
Its a little faster than doing multiple passes with AdvReplaceInFile, further improvements in find & replace for individual strings will make it faster still. | Its a little faster than doing multiple passes with [[More advanced replace text in file|AdvReplaceInFile]], further improvements in find & replace for individual strings will make it faster still. | ||
== Example Usage == | == Example Usage == | ||
Line 25: | Line 23: | ||
Push "@@foo@@" ; string to find | Push "@@foo@@" ; string to find | ||
Push "bar" ; string to replace it with | Push "bar" ; string to replace it with | ||
Call StrRep ; see elsewhere in NSIS | Call StrRep ; see elsewhere in NSIS Wiki | ||
; the string to replace in is at the top of the stack again | ; the string to replace in is at the top of the stack again | ||
Push "@@tellytubby@@" ; string to find | Push "@@tellytubby@@" ; string to find | ||
Line 80: | Line 78: | ||
</highlight-nsis> | </highlight-nsis> | ||
[[ | [[Category:Text Files Manipulation Functions]] |
Latest revision as of 21:36, 2 September 2005
Author: bazzargh (talk, contrib) |
Description
There's other versions of find and replace that allow you to find and replace a single string in a file, but they don't deal with multiple replacements on a single line, or replacements of multiple patterns. I've written an alternative that reads and writes a file, calling a supplied function for every line, so you can make that function do the multiple replacements; thus doing all your replacements in a single pass.
Its a little faster than doing multiple passes with AdvReplaceInFile, further improvements in find & replace for individual strings will make it faster still.
Example Usage
GetFunctionAddress $R0 ReplaceInSQL ; handle to callback fn Push $R0 Push "$INSTDIR\template.sql" ; file to replace in Call ReplaceInFile
Where ReplaceInSQL (or any function of your choosing) looks like:
Function ReplaceInSQL ; save R1 Push $R1 Exch ; A sequence of replacements. ; the string to replace in is at the top of the stack Push "@@foo@@" ; string to find Push "bar" ; string to replace it with Call StrRep ; see elsewhere in NSIS Wiki ; the string to replace in is at the top of the stack again Push "@@tellytubby@@" ; string to find Push "againagain" ; string to replace it with Call StrRep ; and so on ; restore stack Exch Pop $R1 FunctionEnd
The Function
Function ReplaceInFile Exch $R0 ;file name to search in Exch Exch $R4 ;callback function handle Push $R1 ;file handle Push $R2 ;temp file name Push $R3 ;temp file handle Push $R5 ;line read GetTempFileName $R2 FileOpen $R1 $R0 r ;file to search in FileOpen $R3 $R2 w ;temp file loop_read: ClearErrors FileRead $R1 $R5 ;read line Push $R5 ; put line on stack Call $R4 Pop $R5 ; read line from stack IfErrors exit FileWrite $R3 $R5 ;write modified line Goto loop_read exit: FileClose $R1 FileClose $R3 SetDetailsPrint none Delete $R0 Rename $R2 $R0 Delete $R2 SetDetailsPrint both ; pop in reverse order Pop $R5 Pop $R3 Pop $R2 Pop $R1 Pop $R4 Pop $R0 FunctionEnd