Replace strings scripts not done good job

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
goodywp
Posts: 250
Joined: 31 Jul 2017 09:57

Replace strings scripts not done good job

#1 Post by goodywp » 04 Feb 2022 15:28

Hi All,

I have one text file (index.txt) need replace strings. And also I have a variable file as pkg_data_temp.txt

Now I used this below scripts to replace, and most string works fine except two strings only replaced the first part, the remaining is still old

Code: Select all

for /f "tokens=1-2 delims=" %%A in (C:\temp\pkg_data_temp.txt) do call :schemes %%A %%B 

EXIT /B %ERRORLEVEL%


:schemes
set osch=%~1
set nsch=%~2

echo %osch%
echo %nsch%

cd C:\temp

::index.txt
Set "search=%osch%"
Set "replace=%nsch%"
Set "textfile=index.txt"
Set "newfile=indesnew.txt"
(
	For /F "Tokens=1* Delims=:" %%A In ('FindStr /N "^" "%textfile%"') Do (
		If "%%B"=="" (
			Echo=
		) Else (
			Set "line=%%B"
			SetLocal EnableDelayedExpansion
			Set "line=!line:%search%=%replace%!"
			Echo=!line!
			EndLocal
		)
	)
)>"%newfile%"
Del "%textfile%"
Ren "%newfile%" "%textfile%"


::Readme-how-to-use-this-package.txt
Set "search=%osch%"
Set "replace=%nsch%"
Set "textfile=Readme-how-to-use-this-package.txt"
Set "newfile=indesnew.txt"
(
	For /F "Tokens=1* Delims=:" %%A In ('FindStr /N "^" "%textfile%"') Do (
		If "%%B"=="" (
			Echo=
		) Else (
			Set "line=%%B"
			SetLocal EnableDelayedExpansion
			Set "line=!line:%search%=%replace%!"
			Echo=!line!
			EndLocal
		)
	)
)>"%newfile%"
Del "%textfile%"
Ren "%newfile%" "%textfile%"

ping -n 1 127.0.0.1 >NUL

EXIT /B %ERRORLEVEL%
pkg_data_temp.txt is as below
+++++++++++
"T501-08680-0103,0501-08690-0100,T503-08961-0100,T501-08699-0100" "T501-08665-0103,T504-08896-0100,0501-08658-0100,T504-08961-0100"
"T503-08667-0108" "T504-08667-0108"
"T503-08667-0109,T503-08939-0100" "T504-08667-0109,T504-08939-0100"
"T503-08667-0108,T501-08699-0100,T503-08966-0100" "T504-08667-0108,T504-08896-0100,T504-08966-0100"
"T503-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100" "T504-08667-0108,T504-08896-0100,T504-08961-0100,T504-09055-0101"
"T503-08667-0105,T501-08699-0100" "T504-08667-0105,T504-08896-0100"
"T503-08667-0109,T501-08699-0100,T503-08961-0100" "T504-08667-0109,T504-08896-0100,T504-08961-0100"

+++++++++++

This is old text looks like
  • 852046 Version: 0912 (T503-08667-0109,T503-08939-0100)
    852047 Version: 0912
    852059 Version: 0912 (T503-08667-0108,T501-08699-0100,T503-08966-0100)
    852060 Version: 0912 (T503-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100)
    852063 Version: 0912
    852069 Version: 1012 (T503-08667-0105,T501-08699-0100)
    NAR_Apps_Signed_Resources
    829549 Version: 1012
    829625 Version: N/A
    844330 Version: N/A
    847901 Version: N/A
    T3Admin Version: N/A
    852046 Version: 0912
    SRED_Comp Version: 0912
    NAR_Apps_Signed_Resources_CA
    852059 Version: 0912
    NAR KIA
    929500 Version: 0627 (T501-08680-0103,0501-08690-0100,T503-08961-0100,T501-08699-0100)
    NAR TSA
    829501 Version: 0662 (T503-08667-0109,T501-08699-0100,T503-08961-0100)
    NarEmvService
The new text file after replaced
  • 852046 Version: 0912 (T504-08667-0109,T504-08939-0100)
    852047 Version: 0912
    852059 Version: 0912 (T504-08667-0108,T501-08699-0100,T503-08966-0100)
    852060 Version: 0912 (T504-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100)
    852063 Version: 0912
    852069 Version: 1012 (T504-08667-0105,T504-08896-0100)
    NAR_Apps_Signed_Resources
    829549 Version: 1012
    829625 Version: N/A
    844330 Version: N/A
    847901 Version: N/A
    T3Admin Version: N/A
    852046 Version: 0912
    SRED_Comp Version: 0912
    NAR_Apps_Signed_Resources_CA
    852059 Version: 0912
    NAR KIA
    929500 Version: 0627 (T501-08665-0103,T504-08896-0100,0501-08658-0100,T504-08961-0100)
    NAR TSA
    829501 Version: 0662 (T504-08667-0109,T504-08896-0100,T504-08961-0100)
    NarEmvService
So from the new text file, there are two lines not replaced very well which I highlight in bold still old, what happened?

penpen
Expert
Posts: 2002
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Replace strings scripts not done good job

#2 Post by penpen » 07 Feb 2022 07:22

The program repeatedly call the function ":schemes", that replaces one string in a text file with another, based on the content of "pkg_data_temp.txt", which is processed line by line from top to down.

The issue then is caused by the fact that some of the lines to replace are also part of other lines you want to replace, for example:

Code: Select all

T503-08667-0108
T503-08667-0108,T501-08699-0100,T503-08966-0100
T503-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100
After you have replaced "T503-08667-0108", then the text file doesn't contain any occurency of
"T503-08667-0108,T501-08699-0100,T503-08966-0100" or
"T503-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100"
anymore and therefore of course won't be replaced.

Depending on whether or not you want to allow such partial line replacements, it might be sufficient to simply change the order of lines in "pkg_data_temp.txt" (such that no string to be replaced, is contained in a later string to be replaced*), or you have to change the program logic.

*) So that order might or might not help you:

Code: Select all

"T501-08680-0103,0501-08690-0100,T503-08961-0100,T501-08699-0100" "T501-08665-0103,T504-08896-0100,0501-08658-0100,T504-08961-0100"
"T503-08667-0109,T503-08939-0100" "T504-08667-0109,T504-08939-0100"
"T503-08667-0108,T501-08699-0100,T503-08966-0100" "T504-08667-0108,T504-08896-0100,T504-08966-0100"
"T503-08667-0108,T503-09055-0101,T501-08699-0100,T503-08961-0100" "T504-08667-0108,T504-08896-0100,T504-08961-0100,T504-09055-0101"
"T503-08667-0108" "T504-08667-0108"
"T503-08667-0105,T501-08699-0100" "T504-08667-0105,T504-08896-0100"
"T503-08667-0109,T501-08699-0100,T503-08961-0100" "T504-08667-0109,T504-08896-0100,T504-08961-0100"

penpen

goodywp
Posts: 250
Joined: 31 Jul 2017 09:57

Re: Replace strings scripts not done good job

#3 Post by goodywp » 07 Feb 2022 07:56

Thanks @penpen for your finding out the issue. But the content of "pkg_data_temp.txt" is supposed to be not changed manually.
I thought that the double quote should do the job as a whole string instead of only parse by comma?
"T503-08667-0108,T501-08699-0100,T503-08966-0100"

Is any way we can change the program logic to avoid this issue? Or to make sure the string inside quote can be replaced as a whole string?

Thanks

penpen
Expert
Posts: 2002
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Replace strings scripts not done good job

#4 Post by penpen » 07 Feb 2022 13:03

Yes, within batch the double quote guarantees you to parse the string as a whole.
But you then replace the string without those doublequotes (which is exactly, what you want, because there are no double quotes int the text files you change).

The question then is, do you want to allow partial string replacements in the text files, or do you only want to replace entire strings within the parentheses (between the characters '(' and ')').
If you want that, then the fix is pretty easy:
Just search and replace strings with added parentheses.

If not, you need to find out what exactly you want to have changed, since it seems to be unclear, at least to me.


penpen

Aacini
Expert
Posts: 1886
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Replace strings scripts not done good job

#5 Post by Aacini » 07 Feb 2022 18:04

The simplest way to solve your problem is processing the replacement strings from longest to shortest and the simplest way to do that without change the content of "pkg_data_temp.txt" is changing this line:

Code: Select all

for /f "tokens=1-2 delims=" %%A in (C:\temp\pkg_data_temp.txt) do call :schemes %%A %%B 
... by these two:

Code: Select all

for /f "tokens=1-2" %%A in (C:\temp\pkg_data_temp.txt) do set "scheme[%%~A]=%%~B"
for /f "tokens=2-3 delims=[]=" %%A in ('set scheme[') do call :schemes "%%A" "%%B"
Antonio

PS - Your original code have an error in this line:

Code: Select all

for /f "tokens=1-2 delims=" %%A in (C:\temp\pkg_data_temp.txt) do call :schemes %%A %%B 
The delims= part cause that the %%B value be empty always. However, the space and the second string (both with quotes) are also assigned to %%A so the end result of call :schemes %%A %%B is as expected anyway...

goodywp
Posts: 250
Joined: 31 Jul 2017 09:57

Re: Replace strings scripts not done good job

#6 Post by goodywp » 08 Feb 2022 08:58

Aacini wrote:
07 Feb 2022 18:04
The simplest way to solve your problem is processing the replacement strings from longest to shortest and the simplest way to do that without change the content of "pkg_data_temp.txt" is changing this line:

Code: Select all

for /f "tokens=1-2 delims=" %%A in (C:\temp\pkg_data_temp.txt) do call :schemes %%A %%B 
... by these two:

Code: Select all

for /f "tokens=1-2" %%A in (C:\temp\pkg_data_temp.txt) do set "scheme[%%~A]=%%~B"
for /f "tokens=2-3 delims=[]=" %%A in ('set scheme[') do call :schemes "%%A" "%%B"
Antonio

PS - Your original code have an error in this line:

Code: Select all

for /f "tokens=1-2 delims=" %%A in (C:\temp\pkg_data_temp.txt) do call :schemes %%A %%B 
The delims= part cause that the %%B value be empty always. However, the space and the second string (both with quotes) are also assigned to %%A so the end result of call :schemes %%A %%B is as expected anyway...
It works very well! Thanks Antonio!

Post Reply