Replace string with a new line in Batch - batch-file

set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
SET memoli=%token:QMZ=%NL%%%
echo %memoli%>>%tmp%\list2.txt
I cant change the string "QMZ" with a new line. How to do that?

Very simple
setlocal EnableDelayedExpansion
set "token=HelloQMZworld"
echo !token:QMZ=^
!
It works as the batch parser parses first the multiline caret and replace it with a single linefeed.
Then in the delayed expansion phase it replaces the QMZ with a single linefeed, which is legal in that phase.
To set a new variable with the replaced string simply use
setlocal EnableDelayedExpansion
set "token=HelloQMZworld"
set newVal=!token:QMZ=^
!
echo !newVal!

set LF=^
rem ** Two empty lines required
FOR /F "delims=" %%a in ("%token:QMZ=!LF!%") do (
echo %%a>>%tmp%\list2.txt
)
I was just wandering in the codes and I just did this unconsciously. But it does the trick.

Related

Separate batch string, remove substr

I have the following string:
9/14/22 11:00:12,,,0,0,,,,,,
I need to remove 9/14/22 11:00:12 so I only have ,,,0,0,,,,,, left over.
#echo off
set str=9/14/22 11:00:12,,,0,0,,,,,,
FOR /F "tokens=1* delims=," %%a in ("%str%") DO (
set REMOVE_STR=%%a
)
set REMAINING_STR=%str:;%REMOVE_STR%;=%
echo New string: %REMAINING_STR%
The output is just the original string, so I know there's a problem with the substr removal step. But, I can't figure out what I'm doing wrong.
You need delayed expansion to use variables inside a code block that you defined/changed within the same block:
#echo off
setlocal enabledelayedexpansion
set str=9/14/22 11:00:12,,,0,0,,,,,,
FOR /F "tokens=1 delims=," %%a in ("%str%") DO (
set "remaining_str=!str:%%a=!"
echo New string: !Remaining_Str!
)
Output:
New string: ,,,0,0,,,,,,
You don't need a for loop, or delayed expansion for that task, you can do it with direct variable expansion and sustitution, just like this:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "str=9/14/22 11:00:12,,,0,0,,,,,,"
Set "REMAINING_STR=,%str:*,=%
Echo New string: %REMAINING_STR%
The above substitutes everything up to, and including, the first comma, with nothing, in the expanded variable, and precedes that with the initially first removed comma.
You could alternatively substitute everything up to, and including, the first comma, with a comma, like this:
Set "REMAINING_STR=%str:*,=,%

Extract a GUID from XML in batch script

I have a string
<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>
I am trying to trim out DA7C36F0-A749-4CC5-9575-398C06039325 from this line.
To begin with I tried to set this string in a variable but I am not able to do that may be because of < and ? in string, I tried:
set "var=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
But later I was able to fetch the string somehow at runtime and now I have the variable
line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>
I am not able to figure out how can I trim only value i.e DA7C36F0-A749-4CC5-9575-398C06039325 out of this variable using batch script.
I gave it a try to trim suffix at least with:
set "line=%line:"?>%"
But getting error, can anyone help with better approach?
Note: the spaces are included in string
You can split the string using " as a delimiter, but since quotes are used to specify for loop options, the syntax looks a little different than usual:
#echo off
setlocal enabledelayedexpansion
set "line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
echo !line!
for /f tokens^=2^ delims^=^" %%A in ("!line!") do set "line=%%A"
echo !line!
You may use this very simple trick:
#echo off
setlocal EnableDelayedExpansion
set "var=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
set "i=0" & set "v0=%var:"=" & set /A i+=1 & set "v!i!=%"
echo Desired string: [%v1%]
If you want to know how this works, remove the #echo off line and carefully review what appears in the screen...
Your command line:
set "line=%line:"?>%"
does not make sense, because there is an =-sign missing (refer to sub-string substitution):
set "line=%line:"?>=%"
To trim away the unwanted prefix you could remove everything up to the first quotation mark:
set "line=%line:*"=%"
However, this only works when you do that after having removed the suffix, because you are dealing with unbalanced quotation marks, which are problematic together with immediate variable expansion. If you want to change the order, you have to implement escaping in order not to exhibit the redirection operator > unquoted:
set ^"line=%line:*"=%"
set "line=%line:"?>=%"
To avoid the need of escaping depending on the input string, use delayed variable expansion, like this:
set "line=<?define customGUID= "DA7C36F0-A749-4CC5-9575-398C06039325"?>"
set line
rem // First enable delayed expansion:
setlocal EnableDelayedExpansion
rem // Then apply it by replacing `%` with `!`:
set "line=!line:*"=!"
set "line=!line:"?>=!"
set line
rem // This restores the previous state:
endlocal
rem // At this point changes in the variable are no longer available due to localisation:
set line

How remove the | character from variable

I've a code like below:
FOR /F "tokens=*" %%B IN ('%*') DO (
ECHO %%B
SET data=%%B
ECHO %data%
)
The %%B contains one or more than one | character, for example the value of %%B is First | Second | Third. The SET data=%%B or SET data="%%B" function doesn't work. When %data% is called back, it shows Echo is off.
I need to remove the | character from %%B and save it to a %data% variable. But I don't know how?
I will be grateful if any solution has been provided from anyone....
The first solution is using:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F delims^=^ eol^= %%B in ('%*') do (
set "data=%%B"
set "data=!data:|=!"
echo(!data!
)
endlocal
tokens=* results in getting assigned to loop variable B the entire line with leading spaces/tabs removed while delims= results in getting assigned to the loop variable B the entire line including leading spaces/tabs. So the definition of an empty list of delimiters is better in general.
FOR ignores by default empty lines and lines starting with a semicolon because of ; is interpreted by default as end of line character. For that reason the uncommon, not double quoted option string delims^=^ eol^= is used here to define an empty list of delimiters and no end of line character. The caret character ^ is used to escape the next character to get it interpreted as literal character and not as argument separator although not enclosed in a double quoted argument string.
But there is one problem with this solution: A line containing one or more exclamation marks ! is not processed correct because Windows command processor interprets on command line set "data=%%B" each ! as begin/end of a delayed environment variable reference and replaces the string between two exclamation marks by the current value of the environment variable with that name or nothing on no variable existing with such a name and removes everything after ! if there is no more !.
There are at least three solutions.
The first one is enabling and disabling delayed expansion within the loop.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F delims^=^ eol^= %%B in ('%*') do (
set "data=%%B"
setlocal EnableDelayedExpansion
set "data=!data:|=!"
echo(!data!
endlocal
)
endlocal
Please read this answer for details about the commands SETLOCAL and ENDLOCAL as they do much more than just toggling delayed expansion on/off in the loop.
( between echo and value of environment variable data is used in case of a line contains only | without or with additionally just spaces/tabs resulting in data becoming either undefined or a string consisting only of spaces/tabs. A space between echo and !data! would be on execution just the command echo  with an ignored space and 0 or more spaces/tabs resulting in getting output ECHO is off. instead of an empty line or a line with just spaces/tabs. The opening round bracket prevents that and is interpreted by cmd.exe as separator between command echo and its argument string which begins in this case always with (. ECHO ignores the first character of the argument string on output as long as the argument string is not /? and so ( is never output.
The second solution is using a subroutine:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F delims^=^ eol^= %%B in ('%*') do (
set "data=%%B"
call :ProcessLine
)
endlocal
goto :EOF
:ProcessLine
set "data=%data:|=%"
echo(%data%
goto :EOF
Note: echo %data% can result in unexpected behavior if the line contains characters like the redirection operators < and > or the operator & as Windows command processor executes echo(%data% after substituting %data% with current string of environment variable data. Even set "data=%data:|=%" can be problematic depending on line containing " and <>&. So this solution is really not safe.
See also Where does GOTO :EOF return to?
The third solution is using a "double percent" environment variable reference and using command CALL to force a double parsing of the command line containing %%variable%% instead of just %variable% as usual.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F delims^=^ eol^= %%B in ('%*') do (
set "data=%%B"
call set "data=%%data:|=%%"
call echo(%%data%%
)
endlocal
Note Also this solution is not really safe depending on the data as the second solution.
See also How does the Windows Command Interpreter (CMD.EXE) parse scripts?
Windows command processor is designed for executing commands and applications and not for reformatting or processing CSV files using vertical bar as delimiter/separator.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
set /?
setlocal /?
And read also answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? for the reason using the syntax set "variable=value" instead of set variable=value or set variable="value".

Windows Batch:string replacement

The following batch file accepts a parameter which is a path and filename.
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET filename=%~1
echo !filename!
ENDLOCAL
The filename, when received as a parameter will always be formatted using forward slashes.
In order to replace the forwardshlashes with backslashes, I tried this:
SET filename=!filename:/=\!
But that's not working.
What is the simplest way to do string replacement in a windows batch file?
Thanks
First of all you need to remove the space after =:
SET filename=%~1
Otherwise the space will become part of your variable.
To replace / with \ you have to use % instead of !:
SET filename=!filename:/=\!
Further, there is nothing in your code that would require ENABLEEXTENSIONS so you can skip it.
EDIT:
This is my code of something.bat:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET file=%~1
SET file=!file:\=/!
ECHO !file!
Calling the something.bat ABC/DEF/GHI results in the output ABC\DEF\GHI.
You have a problem when you set the variable
v...v. Initial and ending spaces included in value
SET filename = %~1
^........ Space included in variable name
As the variable is not %filename%, but %filename %, your replacement fails. For a string replacement approach you can use
#echo off
setlocal enableextensions disabledelayedexpansion
set "filename=%~1"
set "filename=%filename:/=\%"
echo %filename%
or, still better, this case can be solved using argument modifiers
#echo off
setlocal enableextensions disabledelayedexpansion
set "filename=%~f1"
echo %filename%

substitute a regex in a string in batch

I need to delete everything starting with a word from a string in a windows batch script.
For example if I have the string:
This is my line delete from here.
I want to delete everything starting with the word delete and I need to obtain:
This is my line.
I have tryed this:
set line="This is my line delete from here"
set word="delete"
set delete="!word!*";
set line=!line:%delete%=!
It doesn't work what I have tryed, I have activated delayed expansion, and I am not sure if this: "set line=!line:%delete%=!" works. I have tryed this too "set line=!line:!delete!=!" but doesn't work either. I am new with batch scripting.
UPDATE:
In a loop I can only do delayed expansion, and this code doesn't work:
#ECHO OFF
setlocal
for /F "delims= " %%A in (temp.txt) do (
set "line=This is my line delete from here"
ECHO original:%line%:
set "word=delete"
CALL set "delete=%%line:*%word%=%%"
ECHO delete the "%word%%delete%" part
CALL set "line=%%line:%word%%delete%=%%"
ECHO final :%line%:
)
endlocal
Output:
original::
=%" was unexpected at this time.
delete the "" part
=%" was unexpected at this time.
final ::
But if I remove the for from the code above, the output is:
original:This is my line delete from here:
delete the "delete from here" part
final :This is my line :
My question is how can I do the same thing in a loop, with delayed expansion, as with normal expansion. I need in other words late expansion for both variables in the substitution expression the inner and the outer (set "delete=!line:*!word!=!", doesn't work). I can not find any documentation on that.
Thanks.
#ECHO OFF
SETLOCAL
set "line=This is my line delete from here"
ECHO original:%line%:
set "word=delete"
CALL set "delete=%%line:*%word%=%%"
ECHO delete the "%word%%delete%" part
CALL set "line=%%line:%word%%delete%=%%"
ECHO final :%line%:
GOTO :EOF
This should show you the steps.
First, delete the part up to and including the word. Then delete the word and the rest-of-line (in delete)
Note the placement of the quotes - to control the set not the value assigned.
I have read this and the updated code based on Magoo's answer:
#ECHO OFF
setlocal
for /F "delims= " %%A in (temp.txt) do (
set "line=This is my line delete from here"
set "word=delete"
echo line is: !line!
for /f "delims=" %%a in ("!word!") do set delete=!line:*%%a=!
echo delete is: !delete!
for /f "delims=" %%a in ("!word!!delete!") do set line=!line:%%a=!
echo line is: !line!
)
endlocal

Resources