More advanced replace text in file: Difference between revisions
From NSIS Wiki
Jump to navigationJump to search
No edit summary |
(→Code) |
||
(37 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
== Description == | == Description == | ||
This function allows you to replace pieces of text in a file. | This function allows you to replace pieces of text in a file. | ||
You have the option of replacing text from the xth times of its occurring, and y times replacement of the text from that xth occurrence onwards. | |||
Just copy the full code underneath in a file | Just copy the full code underneath in a text file with notepad, rename it: ReplaceInFile3.nsh and save it in the Include folder of your NSIS installation folder. You should run your installer.exe file in administrator mode which grants you authorization for modifying files in directories (Otherwise the code will be overlooked with no warning). | ||
== Usage 0 == | == Usage 0 == | ||
Line 10: | Line 10: | ||
OutFile "my_installer.exe" | OutFile "my_installer.exe" | ||
--- maybe some code | ;--- maybe some code here | ||
!include ReplaceInFile3.nsh | |||
;--- maybe some code here | |||
Section "my_section" | Section "my_section" | ||
--- maybe some code | ;--- maybe some code here | ||
StrCpy $OLD_STR 'the_old_string' | StrCpy $OLD_STR 'the_old_string' | ||
Line 24: | Line 28: | ||
StrCpy $FILE_TO_MODIFIED 'the_file_to_be_modified' | StrCpy $FILE_TO_MODIFIED 'the_file_to_be_modified' | ||
!insertmacro ReplaceInFile $OLD_STR $FST_OCC $NR_OCC $REPLACEMENT_STR $FILE_TO_MODIFIED | !insertmacro ReplaceInFile $OLD_STR $FST_OCC $NR_OCC $REPLACEMENT_STR $FILE_TO_MODIFIED ;job done | ||
;MessageBox MB_OK|MB_ICONINFORMATION "REPLACEMENT_STR = $REPLACEMENT_STR" | ;MessageBox MB_OK|MB_ICONINFORMATION "REPLACEMENT_STR = $REPLACEMENT_STR" | ||
--- maybe some code | ;--- maybe some code here | ||
SectionEnd | SectionEnd | ||
Line 37: | Line 41: | ||
Push hello #text to be replaced | Push hello #text to be replaced | ||
Push blah #replace with | Push blah #replace with | ||
Push 3 #start replacing | Push 3 #start replacing at the 3rd occurrence | ||
Push 4 #replace | Push 4 #replace 4 occurrences onwards, in all | ||
Push | Push temp1.bat #file to replace in, in the current directory | ||
Call AdvReplaceInFile | Call AdvReplaceInFile | ||
</highlight-nsis> | </highlight-nsis> | ||
Line 47: | Line 51: | ||
Push hello #text to be replaced | Push hello #text to be replaced | ||
Push blah #replace with | Push blah #replace with | ||
Push 3 #start replacing | Push 3 #start replacing at 3rd occurrence | ||
Push all #replace all other occurrences | Push all #replace all other occurrences | ||
Push C:\temp1.bat #file to replace in | Push C:\temp1.bat #file to replace in | ||
Line 59: | Line 63: | ||
Push all #replace all occurrences | Push all #replace all occurrences | ||
Push all #replace all occurrences | Push all #replace all occurrences | ||
Push C:\temp1. | Push 'C:\Program Files\temp1.info' #file to replace in | ||
Call AdvReplaceInFile | Call AdvReplaceInFile | ||
</highlight-nsis> | </highlight-nsis> | ||
== Code == | == Code == | ||
<highlight-nsis> | |||
/* | /* | ||
First occurrence to be replaced: FST_OCC. FST_OCC = all, | First occurrence to be replaced: FST_OCC. | ||
if FST_OCC greater than the number of occurences: no alteration of the file | FST_OCC = all, renders the same as FST_OCC = 1. | ||
if FST_OCC greater than the number of occurences in the file: no alteration of the file, | |||
FST_OCC negative or 0 will leave the file content unchanged no matter the NR_OCC value. | |||
Nr max of occurrences replaced onwards: NR_OCC, | Nr max of occurrences replaced onwards: NR_OCC, | ||
if NR_OCC = all --> replacement as long as a string to be replaced is found | if NR_OCC = all --> replacement as long as a string to be replaced is found, | ||
if NR_OCC = integer, replaces up to NR_OCC occurrences provided they exist | if NR_OCC = stritly positive integer, replaces up to NR_OCC occurrences provided they exist, | ||
NR_OCC | NR_OCC negative or 0 yields the same as all. | ||
Order to run down and search the file: from left to right and top down. | Order to run down and search the file: from left to right and top down. | ||
REPLACEMENT_STR, OLD_STR should be less than 1024 characters long. | REPLACEMENT_STR, OLD_STR, read line should be less than 1024 characters long. | ||
For NSIS Unicode, FILE_TO_MODIFIED must be utf-8 encoded. | |||
*/ | */ | ||
Line 126: | Line 134: | ||
FileOpen $R1 $0 r ;FILE_TO_MODIFIED file to search in | FileOpen $R1 $0 r ;FILE_TO_MODIFIED file to search in | ||
FileOpen $R0 $R6 w ;temp file | FileOpen $R0 $R6 w ;temp file | ||
StrLen $R3 $4 ;the length of OLD_STR | StrLen $R3 $4 ;the length of OLD_STR | ||
StrCpy $R4 0 ;counter initialization | StrCpy $R4 0 ;counter initialization | ||
Line 137: | Line 145: | ||
StrCpy $5 -1 ;cursor, start of read line chunk | StrCpy $5 -1 ;cursor, start of read line chunk | ||
StrLen $7 $R2 ; | StrLen $7 $R2 ;read line length | ||
IntOp $5 $5 - $7 ;cursor initialization | IntOp $5 $5 - $7 ;cursor initialization | ||
StrCpy $7 $R2 ;$7 contains read line | StrCpy $7 $R2 ;$7 contains read line | ||
Line 145: | Line 153: | ||
StrCmp $5 0 file_write ;end of line has been reached | StrCmp $5 0 file_write ;end of line has been reached | ||
StrCpy $6 $7 $R3 $5 ;a chunk of read line of length OLD_STR | StrCpy $6 $7 $R3 $5 ;a chunk of read line of length OLD_STR | ||
StrCmp $6 $4 0 loop_filter ;continues | StrCmp $6 $4 0 loop_filter ;continues to search OLD_STR if no match | ||
StrCpy $8 $7 $5 ;left part | StrCpy $8 $7 $5 ;left part | ||
Line 160: | Line 168: | ||
IntOp $R4 $R4 + 1 ;counter incrementation | IntOp $R4 $R4 + 1 ;counter incrementation | ||
;MessageBox MB_OK|MB_ICONINFORMATION \ | ;MessageBox MB_OK|MB_ICONINFORMATION \ | ||
;"count | ;"count R4 = $R4, fst_occ = $2" | ||
StrCmp $2 all follow_up ;exchange ok, then goes to search the next OLD_STR | StrCmp $2 all follow_up ;exchange ok, then goes to search the next OLD_STR | ||
IntCmp $R4 $2 follow_up ;no exchange until FST_OCC has been reached, | IntCmp $R4 $2 follow_up ;no exchange until FST_OCC has been reached, | ||
Line 170: | Line 178: | ||
IntOp $R5 $R5 + 1 ;counter incrementation | IntOp $R5 $R5 + 1 ;counter incrementation | ||
;MessageBox MB_OK|MB_ICONINFORMATION \ | ;MessageBox MB_OK|MB_ICONINFORMATION \ | ||
;"count | ;"count R5 = $R5, nbr_occ = $1" | ||
StrCmp $1 all exchange_ok ;goes to exchange OLD_STR with REPLACEMENT_STR | StrCmp $1 all exchange_ok ;goes to exchange OLD_STR with REPLACEMENT_STR | ||
IntCmp $R5 $1 finalize ;proceeding exchange until NR_OCC has been reached | IntCmp $R5 $1 finalize ;proceeding exchange until NR_OCC has been reached | ||
exchange_ok: | exchange_ok: | ||
IntOp $5 $5 + $R3 ;updating | IntOp $5 $5 + $R3 ;updating cursor | ||
StrCpy $7 $9 ;updating line | StrCpy $7 $9 ;updating read line with forster read line | ||
Goto loop_filter ;goes searching the same read line | Goto loop_filter ;goes searching the same read line | ||
Line 216: | Line 224: | ||
Pop $4 | Pop $4 | ||
FunctionEnd | FunctionEnd | ||
</highlight-nsis> | |||
== Versions History == | == Versions History == | ||
; 2020-12-12 | ; 2020-12-12 | ||
: Mild alterations to make it work, and such as it was intended to in the first place. Pascal Dor. | |||
:bug: scans the read line from right to left | |||
:bug: doesn't do the job unless: FST_OCC = NR_OCC = all, and even so not fully. | |||
; 2010-10-09 | ; 2010-10-09 |
Latest revision as of 17:45, 14 December 2020
Author: Afrow UK (talk, contrib) |
Description
This function allows you to replace pieces of text in a file. You have the option of replacing text from the xth times of its occurring, and y times replacement of the text from that xth occurrence onwards. Just copy the full code underneath in a text file with notepad, rename it: ReplaceInFile3.nsh and save it in the Include folder of your NSIS installation folder. You should run your installer.exe file in administrator mode which grants you authorization for modifying files in directories (Otherwise the code will be overlooked with no warning).
Usage 0
OutFile "my_installer.exe" ;--- maybe some code here !include ReplaceInFile3.nsh ;--- maybe some code here Section "my_section" ;--- maybe some code here StrCpy $OLD_STR 'the_old_string' StrCpy $FST_OCC all StrCpy $FST_OCC 2 StrCpy $NR_OCC all StrCpy $NR_OCC 3 StrCpy $REPLACEMENT_STR 'the_new_string' StrCpy $FILE_TO_MODIFIED 'the_file_to_be_modified' !insertmacro ReplaceInFile $OLD_STR $FST_OCC $NR_OCC $REPLACEMENT_STR $FILE_TO_MODIFIED ;job done ;MessageBox MB_OK|MB_ICONINFORMATION "REPLACEMENT_STR = $REPLACEMENT_STR" ;--- maybe some code here SectionEnd
Usage 1
Push hello #text to be replaced Push blah #replace with Push 3 #start replacing at the 3rd occurrence Push 4 #replace 4 occurrences onwards, in all Push temp1.bat #file to replace in, in the current directory Call AdvReplaceInFile
Usage 2
Push hello #text to be replaced Push blah #replace with Push 3 #start replacing at 3rd occurrence Push all #replace all other occurrences Push C:\temp1.bat #file to replace in Call AdvReplaceInFile
Usage 3
Push hello #text to be replaced Push blah #replace with Push all #replace all occurrences Push all #replace all occurrences Push 'C:\Program Files\temp1.info' #file to replace in Call AdvReplaceInFile
Code
/* First occurrence to be replaced: FST_OCC. FST_OCC = all, renders the same as FST_OCC = 1. if FST_OCC greater than the number of occurences in the file: no alteration of the file, FST_OCC negative or 0 will leave the file content unchanged no matter the NR_OCC value. Nr max of occurrences replaced onwards: NR_OCC, if NR_OCC = all --> replacement as long as a string to be replaced is found, if NR_OCC = stritly positive integer, replaces up to NR_OCC occurrences provided they exist, NR_OCC negative or 0 yields the same as all. Order to run down and search the file: from left to right and top down. REPLACEMENT_STR, OLD_STR, read line should be less than 1024 characters long. For NSIS Unicode, FILE_TO_MODIFIED must be utf-8 encoded. */ Var /Global OLD_STR Var /Global FST_OCC Var /Global NR_OCC Var /Global REPLACEMENT_STR Var /Global FILE_TO_MODIFIED !macro ReplaceInFile OLD_STR FST_OCC NR_OCC REPLACEMENT_STR FILE_TO_MODIFIED Push "${OLD_STR}" ;text to be replaced Push "${REPLACEMENT_STR}" ;replace with Push "${FST_OCC}" ; starts replacing onwards FST_OCC occurrences Push "${NR_OCC}" ; replaces NR_OCC occurrences in all Push "${FILE_TO_MODIFIED}" ; file to replace in Call AdvReplaceInFile !macroend Function AdvReplaceInFile Exch $0 ;FILE_TO_MODIFIED file to replace in Exch Exch $1 ;the NR_OCC of OLD_STR occurrences to be replaced. Exch Exch 2 Exch $2 ;FST_OCC: the first occurrence to be replaced and onwards Exch 2 Exch 3 Exch $3 ;REPLACEMENT_STR string to replace with Exch 3 Exch 4 Exch $4 ;OLD_STR to be replaced Exch 4 Push $5 ;incrementing counter Push $6 ;a chunk of read line Push $7 ;the read line altered or not Push $8 ;left string Push $9 ;right string or forster read line Push $R0 ;temp file handle Push $R1 ;FILE_TO_MODIFIED file handle Push $R2 ;a line read Push $R3 ;the length of OLD_STR Push $R4 ;counts reaching of FST_OCC Push $R5 ;counts reaching of NR_OCC Push $R6 ;temp file name GetTempFileName $R6 FileOpen $R1 $0 r ;FILE_TO_MODIFIED file to search in FileOpen $R0 $R6 w ;temp file StrLen $R3 $4 ;the length of OLD_STR StrCpy $R4 0 ;counter initialization StrCpy $R5 -1 ;counter initialization loop_read: ClearErrors FileRead $R1 $R2 ;reading line IfErrors exit ;when end of file has been reached StrCpy $5 -1 ;cursor, start of read line chunk StrLen $7 $R2 ;read line length IntOp $5 $5 - $7 ;cursor initialization StrCpy $7 $R2 ;$7 contains read line loop_filter: IntOp $5 $5 + 1 ;cursor shifting StrCmp $5 0 file_write ;end of line has been reached StrCpy $6 $7 $R3 $5 ;a chunk of read line of length OLD_STR StrCmp $6 $4 0 loop_filter ;continues to search OLD_STR if no match StrCpy $8 $7 $5 ;left part IntOp $6 $5 + $R3 IntCmp $6 0 yes no ;left part + OLD_STR == full line read ? yes: StrCpy $9 "" Goto done no: StrCpy $9 $7 "" $6 ;right part done: StrCpy $9 $8$3$9 ;replacing OLD_STR by REPLACEMENT_STR in forster read line IntOp $R4 $R4 + 1 ;counter incrementation ;MessageBox MB_OK|MB_ICONINFORMATION \ ;"count R4 = $R4, fst_occ = $2" StrCmp $2 all follow_up ;exchange ok, then goes to search the next OLD_STR IntCmp $R4 $2 follow_up ;no exchange until FST_OCC has been reached, Goto loop_filter ;and then searching for the next OLD_STR follow_up: IntOp $R4 $R4 - 1 ;now counter is to be stuck to FST_OCC IntOp $R5 $R5 + 1 ;counter incrementation ;MessageBox MB_OK|MB_ICONINFORMATION \ ;"count R5 = $R5, nbr_occ = $1" StrCmp $1 all exchange_ok ;goes to exchange OLD_STR with REPLACEMENT_STR IntCmp $R5 $1 finalize ;proceeding exchange until NR_OCC has been reached exchange_ok: IntOp $5 $5 + $R3 ;updating cursor StrCpy $7 $9 ;updating read line with forster read line Goto loop_filter ;goes searching the same read line finalize: IntOp $R5 $R5 - 1 ;now counter is to be stuck to NR_OCC file_write: FileWrite $R0 $7 ;writes altered or unaltered line Goto loop_read ;reads the next line exit: FileClose $R0 FileClose $R1 ;SetDetailsPrint none Delete $0 Rename $R6 $0 ;superseding FILE_TO_MODIFIED file with ;temp file built with REPLACEMENT_STR ;Delete $R6 ;SetDetailsPrint lastused Pop $R6 Pop $R5 Pop $R4 Pop $R3 Pop $R2 Pop $R1 Pop $R0 Pop $9 Pop $8 Pop $7 Pop $6 Pop $5 ;These values are stored in the stack in the reverse order they were pushed Pop $0 Pop $1 Pop $2 Pop $3 Pop $4 FunctionEnd
Versions History
- 2020-12-12
- Mild alterations to make it work, and such as it was intended to in the first place. Pascal Dor.
- bug: scans the read line from right to left
- bug: doesn't do the job unless: FST_OCC = NR_OCC = all, and even so not fully.
- 2010-10-09
- Bug fixed that doesn't change "all" occurrences
- 2006-09-28
- Bug fixed that restoring $0~$4 order -- Maxi Ng
- 2005-July-18
- Bug fixed that doesn't replace a text when you have only 1 line in the text file - Mark Bryan Yu
- 2004-Feb-18
- Bug fixed that stopped it replacing parts of text on a line. The bug was only allowing it to replace whole lines.
- 2003-May-27
- Re-written.
Credits
Written by me for modifying batch files.
-Stu (Afrow UK)