Search and replace with quote in batch script - search

I'm trying to search and replace a string containing a double quote with another string but I got some issue.
I'm reading a file line per line, and searching in this line if there's a match for a replace
Example:
%%l contain a line read from a file. For this example, %%l = myVar: "../folder"+var
set s=%%l
set sch="+var
set rpl=val
set s=%s:!sch!=!rpl!%
echo !s!
Here, I want to replace "+var with val
But doing this, it's not working. My echo !s! return "+var=val only
I also tried:
set s=%%l
set rpl=val
set s=%s:"+var=!rpl!%
And it doesn't work.
Any idea?
Thanks

Try changing replace line for this:
set s=!s:%sch%=%rpl%!

Related

How to replace multi-lines of string in a text file by batch script

I need to replace multiple string lines by new values after equal sign
I've already tried with some test data and it's working, issue is that I need to pass full line, but i need to pass part of a line in a text file:
prop.first.name=firstname
I need to pass before "=" (or search) and replace firstname by anything else
I did manage to get something working but it's doing for one line... I have at least 4 lines to be executed with the same command
CALL :modify prop.first.name , myName
CALL :modify prop.last.name , myLastName
:modify
set "source=srcFile.txt"
set "target=tmpFile.txt"
set property=%~1
set value=%~2
setlocal enableDelayedExpansion
(
for /F "tokens=1* delims==" %%a in ('findstr /B "^" %source%') do (
set line=%%b
if defined line echo !line:%property%=%property%=%value%!
)
) > %target%
endlocal
source file looks like:
prop.first.name=firstname
prop.last.name=lastname
prop.pssw.word=password
prop.url.link=alink
I need to replace value after "=" equal sign to an input
The idea is to call a generic function 4 times with different parameters

In CMD substitution, how to remove substring which starts from specific character to the end

In substitution or deletion of sub string from original string, usually uses this form in windows CMD.
set result=%original:<strings_to_be_removed>=<strngs_to_be_newly_substituted>%
So it works for many situation as follows ..
set "original=Questions that may already have your answer"
set "you=%original:that=you%"
set you
you=Questions you may already have your answer
set challenge=%original:Questions=Challenges%
set challenge
challenge=Challenges that may already have your answer
set answer=%original:*your=%
set answer
answer= answer
But I don't know how to substitute or remove sub-string which starts from specific character(or word) to the end of the original string.
For example, suppose I would like to remove sub-string which starts from "that" to the end of the original string. Then I use command as follows and expect result string to be "Questions "
set result=%original:that*=%
But, result string has no difference from original string. No effect occures. Substitution intention fails..
set result
result=Questions that may already have your answer
I used escape character '^', '\' for this case, but no effect..
How to fix this to substitute or remove substring like this type?
How can you substitute or remove substring which starts from specific character(or word) to the end of the original string? Thank you:-)
you can trick the command line parser to do that:
set "original=Questions that may already have your answer"
set result=%original: may =&REM %
set result
sadly, set "result=%original:may=&REM %" doesn't work, so the string should be free from poison characters.
How it works:
replace the word with &REM, which makes your string:
Questions that & REM already have your answer
and the command:
set result=Questions that & REM already have your answer
& is used as a delimiter for commands (try echo hello&echo world, which executes both echo commands). So what's really executed, is two commands:
set result=Questions that
and
REM already have your answer
It also doesn't work with delayed expansion. You can use a subfunction for it instead:
setlocal enabledelayedexpansion
if 1==1 (
set "original=Questions that may already have your answer"
call :substring "!original!"
set result
)
goto :eof
:substring
set org=%~1
set result=%org: may =&REM %
goto :eof

Substitute substring in cmd window

I have the following string in a batch file script:
ABCE#$1 TroubleMaker[FFFFF A=MyCountry US=1 CA=1 JP=1 EU=1
and it's stored in _var,when I do
set _var=%_var:* A=% - it cuts all the characters before " A" (including the 'A') and i'm left with =MyCountry US=1 CA=1 JP=1 EU=1
how can I change the set command to cut also the = mark from the string?
tried set _var=%_var:*==% - didn't work.
Thanks.
#ECHO OFF
SETLOCAL
SET "string=ABCE#$1 TroubleMaker[FFFFF A=MyCountry US=1 CA=1 JP=1 EU=1"
FOR /f "tokens=1*delims==" %%s IN ("%string%") DO SET "string=%%t"
ECHO "%string%"
GOTO :EOF
This assumes that you want to delete up to and including the initial =
The = disturbs the substring replacement syntax, because it contains a = on its own.
You could go for the following work-around:
set _var=%_var:* A=%
set _var=%_var:~1%
The second line constitutes the substring expansion syntax (type set /? for details), which splits off the first character, that is supposed to be a =.
This of course works only if the = immediately follows the A substring.
You can check whether the first character is = before removing it, like:
set _var=%_var:* A=%
if "%_var:~,1%"=="=" set _var=%_var:~1%
If you just want to search for the (first) = character and to ignore the A substring, you could establish a loop structure like this:
:LOOP
if "%_var%"=="" goto :END
if "%_var:~,1%"=="=" (
set _var=%_var:~1%
goto :END
) else (
set _var=%_var:~1%
goto :LOOP
)
:END
This cuts off the first character and checks whether it is a =. If it is, the remaining string is stored in _var and the loop is left; if not, the loop continues checking the next character. The first line is inserted to not hang in case the string does not contain a = character.

Find string with special character in text file and add line break before each occurrence

I have a text file that is one long string like this:
ISA*00*GARBAGE~ST*TEST*TEST~CLP*TEST~ST*TEST*TEST~CLP*TEST~ST*TEST*TEST~CLP*TEST~GE*GARBAGE*~
And I need it to look like this:
~ST*TEST*TEST~CLP*TEST
~ST*TEST*TEST~CLP*TEST
~ST*TEST*TEST~CLP*TEST
I first tried to add a line at every ~ST to split the string up, but I can't for the life of me make this happen. I have tried various scripts, but I thought a find/replace script would work best.
#echo off
setlocal enabledelayedexpansion
set INTEXTFILE=test.txt
set OUTTEXTFILE=test_out.txt
set SEARCHTEXT=~ST
set REPLACETEXT=~ST
for /f "tokens=1,* delims=~" %%A in ( '"type %INTEXTFILE%"') do (
SET string=%%A
SET modified=!string:%SEARCHTEXT%=%REPLACETEXT%!
echo !modified! >> %OUTTEXTFILE%
)
del %INTEXTFILE%
rename %OUTTEXTFILE% %INTEXTFILE%
Found here How to replace substrings in windows batch file
But I'm stuck because (1) the special character ~ makes the code not work at all. It gives me this result:
string:~ST=~ST
The code does nothing at all if using quotes around "~ST". And (2) I can't figure out how to add a line break before ~ST.
The final task for this would be to delete the ISA*00*blahblahblah and ~GE*blahblahblah lines after all splits have been performed. But I am stuck on the splitting at ~ST part.
Any suggestions?
#echo off
setlocal EnableDelayedExpansion
rem Set next variable to the number of "~" chars that delimit the wanted fields, or more
set "maxTokens=7"
rem Define the delimiters that starts a new field
set "delims=/ST/GE/"
for /F "delims=" %%a in (test.txt) do (
set "line=%%a"
set "field="
rem Process up to maxTokens per line;
rem this is a trick to avoid a call to a subroutine that have a goto loop
for /L %%i in (0,1,%maxTokens%) do if defined line (
for /F "tokens=1* delims=~" %%b in ("!line!") do (
rem Get the first token in the line separated by "~" delimiter
set "token=%%b"
rem ... and update the rest of the line
set "line=%%c"
rem Get the first two chars after "~" token like "ST", "CL" or "GE";
rem if they are "ST" or "GE":
for %%d in ("!token:~0,2!") do if "!delims:/%%~d/=!" neq "%delims%" (
rem Start a new field: show previous one, if any
if defined field echo !field!
if "%%~d" equ "ST" (
set "field=~%%b"
) else (
rem It is "GE": cancel rest of line
set "line="
)
) else (
rem It is "CL" token: join it to current field, if any
if defined field set "field=!field!~%%b"
)
)
)
)
Input:
ISA*00*GARBAGE~ST*TEST1*TEST1~CLP*TEST1~ST*TEST2*TEST2~CLP*TEST2~ST*TEST3*TEST3~CLP*TEST3~GE*GARBAGE*~CLP~TESTX
Output:
~ST*TEST1*TEST1~CLP*TEST1
~ST*TEST2*TEST2~CLP*TEST2
~ST*TEST3*TEST3~CLP*TEST3
Don't reinvent the wheel, use a regexp replace tool such as sed or JREPL.BAT:
call jrepl "^.*?~ST(.+?)~GE.*$" "'~ST'+$1.replace(/~ST/g,'\r\n$&')" /jmatch <in.txt >out.txt
The ~ cannot be used as the first character of a search string in the substring substitution syntax %VARIABLE:SEARCH_STRING=REPLACE_STRING%, because it is used to mark the substring expansion %VARIABLE:~POSITION,LENGTH% (type set/? for more information).
Supposing your text file contains a single line of text only and it does not exceed a size of about 8 kBytes, I see the following option for accomplishing your task. This script makes use of the substring substitution syntax %VARIABLE:*SEARCH_STRING=REPLACE_STRING%; the * defines to match everything up to the first occurrence of SEARCH_STRING:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
rem initialise constants:
set "INFILE=test_in.txt"
set "OUTFILE=test_out.txt"
set "SEARCH=ST"
set "TAIL=GE"
rem read single-line file content into variable:
< "%INFILE%" set /P "DATA="
rem remove everything before first `~%SEARCH%`:
set "DATA=~%SEARCH%!DATA:*~%SEARCH%=!"
rem call sub-routine, redirect its output:
> "%OUTFILE%" call :LOOP
endlocal
goto :EOF
:LOOP
rem extract portion right to first `~%SEARCH%`:
set "RIGHT=!DATA:*~%SEARCH%=!"
rem skip rest if no match found:
if "!RIGHT!"=="!DATA!" goto :TAIL
rem extract portion left to first `~%SEARCH%`, including `~`:
set "LEFT=!DATA:%SEARCH%%RIGHT%=!"
rem the last character must be a `~`;
rem so remove it; `echo` outputs a trailing line-break;
rem the `if` avoids an empty line at the beginning;
rem the unwanted part at the beginning is removed implicitly:
if not "!LEFT:~,-1!"=="" echo(!LEFT:~,-1!
rem output `~%SEARCH%` without trailing line-break:
< nul set /P "DUMMY=~%SEARCH%"
rem store remainder for next iteration:
set "DATA=!RIGHT!"
rem loop back if remainder is not empty:
if not "!DATA!"=="" goto :LOOP
:TAIL
rem this section removes the part starting at `~%TAIL%`:
set "RIGHT=!DATA:*~%TAIL%=!"
if "!RIGHT!"=="!DATA!" goto :EOF
set "LEFT=!DATA:%TAIL%%RIGHT%=!"
rem output part before `~%TAIL%` without trailing line-break:
< nul set /P "DUMMY=!LEFT:~,-1!"
goto :EOF
The following restrictions apply to this approach:
the input file contains a single line;
the size of the input file does not exceed about 8 kBytes;
there is exactly one instance of ~GE, that occurs after all instances of ~ST;
there is always at least one character in between two adjacent ~ST instances;
no special characters occur in the file, like: SPACE, TAB, ", %, !, =;

String replace in a file by using batch file. gettting error : < was unexpected at this time batcch file

Could anyone please suggest me how can I replace a string in a file by using scripts? That strings are contain few special characters(example: > < /> “ ” ).
My searchString is as mentioned below
launcher.properties" />
My new string will be as mentioned below
launcher.properties" > <Permission User="Everyone" GenericAll="yes" /> </File>
when I am using below script getting error
#echo off &setlocal
set "search=launcher.properties" />"
set "replace=launcher.properties" > <Permission User="Everyone"
GenericAll="yes" /> </File> "
echo replaceing hte string....2222
set "textfile=home.wxs"
set "newfile=home_t2.wxs"
(for /f "delims=" %%i in (%textfile%) do (
set "line=%%i"
setlocal enabledelayedexpansion
set "line=!line:%search%=%replace%!"
echo(!line!
endlocal
))>"%newfile%"
del %textfile%
rename %newfile% %textfile%
Getting below error:
The system cannot find the path specified.
< was unexpected at this time.
Please help me in this.
For such complicated replacements I would use more complicated script.
You can try replacer.bat (the e? before the file name is for evaluation of unicode sequences - quotes in this case )
call replacer.bat e?home.wxs "launcher.properties\u0022/>" "launcher.properties\u0022 > <Permission User=\u0022Everyone\u0022 GenericAll=\u0022yes\u0022/> </File>"
it is a jscript/bat hybrid and should be saved with .bat extension (you can use it on any windows system without prerequisites).
you can check also FindRepl and JRepl which are more sophisticated tools
I think the error is caused by the (initial) set commands and the way the command line interpreter (CLI) parses double-quotes, because there are double-quotes within the values. The CLI usually takes the second double-quote to end the portion opened by the first double-quote, the fourth closes the third, and so on. For everything in between each found pair of double-quotes "" special characters like separators, redirections, pipes (&, <>, |) are not detected, but they are recognised outside of such pairs.
Supposing there are no said special characters in between double-quoted strings in your input file (for example, "Everyone" or "yes" like in the %replace% string), the following code should work:
#echo off & setlocal
set "search=launcher.properties"" />"
set "replace=launcher.properties"" > <Permission User=""Everyone"" GenericAll=""yes"" /> </File> "
echo replacing hte string....2222
set "textfile=home.wxs"
set "newfile=home_t2.wxs"
(for /F "delims=" %%I in (%textfile%) do (
set "line=%%I"
setlocal enabledelayedexpansion
set "line=!line:"=""!"
set "line=!line:%search%=%replace%!"
set "line=!line:""="!"
echo(!line!
endlocal
)) > "%newfile%"
del /P "%textfile%"
rename "%newfile%" "%textfile%"
What I'm doing here is giving two consecutive double-quotes instead of each one in your search and replace values, and also in each read line from the original file %textfile%, and replace them by a single " after the search-and-replace operations. In between the %% or !! for variable expansion/substitution, double-quotes seem to have no more special meaning.
Note: For checking the final values of search and replace, you cannot use echo because you fall into the same problem like described on top. Instead, type set search or set replace to display the respective values.

Resources