How do I replace all asterixes (or "*") in a string in commandline or
batch?
Set var=This*Is*A*String*
I want to replace all * with a space.
Set var=%var:*= % does not work
Set var=%var:^*= % neither.
I know the cause (from set /?):
Environment variable substitution has been enhanced as follows:
%PATH:str1=str2%
would expand the PATH environment variable, substituting each
occurrence
of "str1" in the expanded result with "str2". "str2" can be the empty
string to effectively delete all occurrences of "str1" from the
expanded
output. "str1" can begin with an asterisk, in which case it will
match
everything from the beginning of the expanded output to the first
occurrence of the remaining portion of str1.
anyone an idea on this?
>How do I replace all asterixes (or "*") in a string in commandline or
>batch?
@echo off
:: Phil Robyn
setlocal
SET "TestVar=Asterisks*should*be*replaced"
set TestVar
set "NewVar="
:loop
for /f "tokens=1* delims=*" %%a in (
"%TestVar%"
) do (set NewVar=%NewVar%_%%a&set TestVar=%%b)
if defined TestVar goto :loop
set TestVar=%NewVar:~1%
set TestVar
> @echo off
>:: Phil Robyn
> setlocal
> SET "TestVar=Asterisks*should*be*replaced"
> set TestVar
> set "NewVar="
>:loop
> for /f "tokens=1* delims=*" %%a in (
> "%TestVar%"
> ) do (set NewVar=%NewVar%_%%a&set TestVar=%%b)
> if defined TestVar goto :loop
> set TestVar=%NewVar:~1%
> set TestVar
I'm afraid that doesn't fulfill the criteria, e.g.
::----- START -----
@ECHO OFF & SETLOCAL ENABLEEXTENSIONS
SET "TESTVAR=This*Is*A**String*"
ECHO/[%TESTVAR%]
SET "NEWVAR="
:LOOP
FOR /F "TOKENS=1* DELIMS=*" %%A IN ("%TESTVAR%") DO (
SET "NEWVAR=%NEWVAR% %%A" & SET "TESTVAR=%%B")
IF DEFINED TESTVAR GOTO LOOP
SET "TESTVAR=%NEWVAR:~1%"
ECHO/[%TESTVAR%]
PAUSE
::------ END ------
As you can see both the multiple asterisks and trailing are missed!
for /F "tokens=*" %%a in ('echo %var% ^| sed -r "s/[*]/ /g"') do set
var=%%a
Greetings,
>I'm afraid that doesn't fulfill the criteria, e.g.
>::----- START -----
> @ECHO OFF & SETLOCAL ENABLEEXTENSIONS
> SET "TESTVAR=This*Is*A**String*"
> ECHO/[%TESTVAR%]
> SET "NEWVAR="
> :LOOP
> FOR /F "TOKENS=1* DELIMS=*" %%A IN ("%TESTVAR%") DO (
> SET "NEWVAR=%NEWVAR% %%A" & SET "TESTVAR=%%B")
> IF DEFINED TESTVAR GOTO LOOP
> SET "TESTVAR=%NEWVAR:~1%"
> ECHO/[%TESTVAR%]
> PAUSE
>::------ END ------
>As you can see both the multiple asterisks and trailing are missed!
Ok, here's a slow way:
@echo off
Set var=****This*Is***A*String**
set c=0
set a=0
set b=1
:loop
call set "cut=%%var:~%c%,1%%"
if "%cut%"=="*" call set "var=%%var:~0,%c%%% %%var:~%b%%%"
set /a c=c+1
set /a b=c+1
call set "cut=%%var:~%c%,1%%"
if defined cut goto :loop
echo "%var%"
pause
OK, then using foxidrive's own parsing routine ...
@echo off
setlocal
SET "TESTVAR= This*Is*A* *String* "
set "testvar=%testvar: =\~%"
for /f "tokens=2 delims=]" %%a in (
'cmd /u/cecho.%Testvar%^|find /v /n ""'
) do (
if %%a==* (
call set "_t=%%_t%% "
) else (
call set "_t=%%_t%%%%a"
)
)
echo [%_t:\~= %]
I added some spaces for effect. Note that this does not work for
Unicode encoded strings.
> How do I replace all asterixes (or "*") in a string
> in commandline or batch?
From the commandline call a script. From a batch script here's a routine
with a demo:
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "v=*a&b*c*****d*e*f"
Echo.v=!v!
Call :Replace v "*" "&"
Echo.v=!v!
Call :Replace v "&" "|"
Echo.v=!v!
Goto :EOF
:Replace
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!"
Set "new="
REM The Tom Lavedas String Length Maneuver (TLSLM)
For /F "delims=:" %%a in (
'(Echo."!%~1!"^& Echo.^)^|FindStr /O .') Do Set /A "$=%%a-6"
For /L %%i in (0,1,%$%) Do (
If "!old:~%%i,1!" EQU "%~2" (
Set "new=!new!%~3"
) Else (
Set "new=!new!!old:~%%i,1!"
)
)
EndLocal & Set "%~1=%new%"
Goto :EOF
Frank
And from that the following might be a good string replacement routine.
:: BEGIN SCRIPT ::::::::::::::::::::::::::::::::::
@Echo OFF
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "v=*a&b*c*****d*e*f"
Echo.v=!v!
Call :ReplaceString v "a&b" "a|b"
Echo.v=!v!
Call :ReplaceString v "*****" " "
Echo.v=!v!
Goto :EOF
:ReplaceString Variable_Name Old_String New_String
:: Case sensitive string replacement.
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!"
Set "new="
REM The Tom Lavedas String Length Maneuver (TLSLM)
For /F "delims=:" %%a in (
'(Echo."!%~1!"^& Echo.^)^|FindStr /O .') Do Set /A "s=%%a-6"
For /F "delims=:" %%a in (
'(Echo."%~2"^& Echo.^)^|FindStr /O .') Do Set /A "o=%%a-5"
Set "skip=0"
For /L %%i in (0,1,%s%) Do (
If !skip! EQU 0 (
If "!old:~%%i,%o%!" EQU "%~2" (
Set "new=!new!%~3" & Set /A "skip=%o%-1"
) Else (
Set "new=!new!!old:~%%i,1!"
)
) Else (Set /A "skip-=1")
)
EndLocal & Set "%~1=%new%"
Goto :EOF
:: END SCRIPT ::::::::::::::::::::::::::::::::::::
Frank
Topli pozdrav
>How do I replace all asterixes (or "*") in a string in commandline or
>batch?
>
>Set var=This*Is*A*String*
>
>I want to replace all * with a space.
You have a few methods to choose from now - and just to warn you they all
have problems with certain characters in the string.
Frank's has issues with !
Tom's has issues with ~ ] ^ and poison characters
They all have issues with %
> Frank's has issues with !
> They all have issues with %
You commented on the character replacement routine but the same could be
said about the string replacement routine.
The percent sign is a problem which needs to be resolved during the
creation of the variable being sent to :Replace and :ReplaceString. If
the percent sign isn't entered correctly it doesn't exist when the
variable is created. If the variable is created as in the demos it
should be doubled:
Set "v=A 50%% increase!"
If it is created some other way, such as on the command line or in a
file, then it should survive as the single character, depending on how
the variable is handled.
The exclamation mark is a very similar problem. If delayed expansion is
enabled then an unescaped exclamation mark will not get to the
replacement routines. If delayed expansion is disabled then the
exclamation mark passes through the replacement routines and cannot be
changed.
Frank
> Frank's has issues with !
I might have resolved that by requiring the calling script to place
everything in variables. This routine will now also delete selected
strings. Here's the new string replacement routine with a demo:
@echo OFF
SetLocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
Set "v=A 50%% increase!" & Set "e=^!" & Set "d=^!^!"
Echo.v=%v%
Call :ReplaceString v e d
Echo.v=%v%
Set "e=%%" & Set "d=0%%"
Call :ReplaceString v e d
Echo.v=%v%
Set "e=0" & Set "d="
Call :ReplaceString v e d
Echo.v=%v%
Goto :EOF
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!"
Set "new=" & Set "r2=" & Set "r3="
If DEFINED %~2 (
For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b"
)
)
If DEFINED %~3 (
For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b"
)
)
REM The Tom Lavedas String Length Maneuver (TLSLM)
For /F "delims=:" %%a in (
'(Echo."!%~1!"^& Echo.^)^|FindStr /O .') Do Set /A "s=%%a-6"
For /F "delims=:" %%a in (
'(Echo."%~2"^& Echo.^)^|FindStr /O .') Do Set /A "o=%%a-5"
Set "skip=0"
For /L %%i in (0,1,%s%) Do (
If !skip! EQU 0 (
If "!old:~%%i,%o%!" EQU "!r2!" (
Set "new=!new!!r3!" & Set /A "skip=%o%-1"
) Else (
Set "new=!new!!old:~%%i,1!"
)
) Else (Set /A "skip-=1")
)
EndLocal & Set "%~1=%new%"
Goto :EOF
I was't able to convert '^!^!' back to '^!'. That might require going
back to individual character replacement.
Frank
Soe osas
> For /F "delims=:" %%a in (
> '(Echo."%~2"^& Echo.^)^|FindStr /O .') Do Set /A "o=%%a-5"
I made a boo-boo. I neglected to change "%~2" to "!%~2!". I think it's
all better now.
@echo OFF
SetLocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
Set "v=A 50%% increase!" & Set "e=^!" & Set "d=^!^!"
Echo.v=%v%
Call :ReplaceString v e d
Set "e=%%" & Set "d=0%%"
Call :ReplaceString v e d
Echo.v=%v%
Set "e=0" & Set "d="
Call :ReplaceString v e d
Set "e=in" & Set "d=de"
Call :ReplaceString v e d
Set "e=^!" & Set "d="
Call :ReplaceString v e d
Set "e=^!" & Set "d=."
Call :ReplaceString v e d
Echo.v=%v%
Goto :EOF
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!" & Set "new=" & Set "r2=" & Set "r3=" & Set "skip=0"
If DEFINED %~2 For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b")
If DEFINED %~3 For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b")
REM The Tom Lavedas String Length Maneuver (TLSLM)
For /F "delims=:" %%a in (
'(Echo."!%~1!"^& Echo.^)^|FindStr /O .') Do Set /A "s=%%a-6"
For /F "delims=:" %%a in (
'(Echo."!%~2!"^& Echo.^)^|FindStr /O .') Do Set /A "o=%%a-5"
For /L %%i in (0,1,%s%) Do (
If !skip! EQU 0 (
If "!old:~%%i,%o%!" EQU "!r2!" (
Set "new=!new!!r3!" & Set /A "skip=%o%-1"
) Else (
Set "new=!new!!old:~%%i,1!"
)
) Else (Set /A "skip-=1")
)
EndLocal & Set "%~1=%new%"
Goto :EOF
Frank
>"Frank P. Westlake" news:heen2j$7cc$1...@news.albasani.net...
>
>> For /F "delims=:" %%a in (
>> '(Echo."%~2"^& Echo.^)^|FindStr /O .') Do Set /A "o=%%a-5"
>
>
>I made a boo-boo. I neglected to change "%~2" to "!%~2!". I think it's
>all better now.
You win some, you lose some.
Your code no longer handles poison characters < > |
> Your code no longer handles poison characters < > |
Thank you, that's very helpful. It looks like I'll have to go back to my
string length routine with the famous math trick, take out the math
trick and use normal math. The difference is that one uses "ECHO >" and
the other 'SET var'.
Back in a few minutes after I rework the routine.
Frank
> Your code no longer handles poison characters < > |
That might just be a problem with the calling script, not the
ReplaceString routine.
In the demo I replaced
Set "e=^!" & Set "d=."
with
Set "e=^!" & Set "d=>"
and output was redirected to a file by:
REM Echo.v=%v%
That isn't the subroutine, just the demo. It would work as !v! but
delayed expansion was disabled, so it needs to either be displayed with
SET
Set v
or to have delayed expansion turned back on for the ECHO:
SetLocal EnableDelayedExpansion & Echo.v=!v! & EndLocal
Does that fix it for you?
Frank
Not very satisfactory, but one could use
@echo off & setlocal enableextensions
set var=This*Is*A*String*
echo %var%
>"%temp%\tmp$$$.vbs" echo WScript.Echo Replace ("%var%", "*","_")
for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set var=%%a
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
set var=%var:_= %
echo %var%
endlocal & goto :EOF
All the best, Timo
--
Prof. Timo Salmi mailto:t...@uwasa.fi ftp & http://garbo.uwasa.fi/
Hpage: http://www.uwasa.fi/laskentatoimi/english/personnel/salmitimo/
Department of Accounting and Finance, University of Vaasa, Finland
Useful CMD script tricks http://www.netikka.net/tsneti/info/tscmd.htm
>"foxidrive" news:3jvlg5hqsej688ljv...@4ax.com...
>
>> Your code no longer handles poison characters < > |
>
>That might just be a problem with the calling script, not the
>ReplaceString routine.
>Does that fix it for you?
Yes, it was just the echo.
I tried this and it doesn't replace the zero.
@echo OFF
SetLocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
Set "v=A 50%% increase!" & Set "e=0" & Set "d=00"
Echo."v=%v%"
Call :ReplaceString v e d
pause
Goto :EOF
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!" & Set "new=" & Set "r2=" & Set "r3=" & Set "skip=0"
If DEFINED %~2 For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b")
If DEFINED %~3 For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b")
REM The Tom Lavedas String Length Maneuver (TLSLM)
For /F "delims=:" %%a in (
'(Echo."!%~1!"^& Echo.^)^|FindStr /O .') Do Set /A "s=%%a-6"
For /F "delims=:" %%a in (
> I tried this and it doesn't replace the zero.
> Set "v=A 50%% increase!" & Set "e=0" & Set "d=00"
> Echo."v=%v%"
> Call :ReplaceString v e d
> pause
> Goto :EOF
Maybe you've had a very busy day. Try 'Echo."v=%v%"' again just before
the pause.
A test of all 7-bit non-alphanumeric characters except quote (") works:
SetLocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
Set "v=@#$%%^^&*()_-+={[}]|\:;'<,>.?/!"
Set "e=@#$%%" & Set "d=[1]"
Call :ReplaceString v e d
Set "e=^^" & Set "d=[2]"
Call :ReplaceString v e d
Set "e=&*()_-+={[}]|\:;'<,>.?/" & Set "d=[3]"
Call :ReplaceString v e d
Set "e=^!" & Set "d=[4]"
Call :ReplaceString v e d
SetLocal EnableDelayedExpansion & Echo.v=!v! & EndLocal
Two problems I've found.
The first problem is that the exclamation mark (!) only works at the end
of the string. Maybe this is proper punctuation enforcement. At other
locations in that special string (@#$%%^^&*()_-+={[}]|\:;'<,>.?/!) it is
either ignored or it causes other characters to be misread.
The second problem is that it behaves differently, and poorly, when that
special string is read from a file. This I don't understand yet. The
string is the same and it appears to be the same when read and stored in
the environment, but the routine balks on redirection characters and
such that it accepts the other way.
I'm going to slow down with this routine and see if I can figure out how
to make it work with everything.
Thank you very much for your help.
Frank
I have only 1 advice for you, DON'T use batch to parse strings/text.
Use a good text processing tool. Its meant for the job. You have used
sed, and that's a good start.
>"foxidrive" news:b25mg5lbcuenpjn8u...@4ax.com...
>
>> I tried this and it doesn't replace the zero.
>
>> Set "v=A 50%% increase!" & Set "e=0" & Set "d=00"
>> Echo."v=%v%"
>> Call :ReplaceString v e d
>> pause
>> Goto :EOF
>
>Maybe you've had a very busy day. Try 'Echo."v=%v%"' again just before
>the pause.
Mea culpa.
Fine tuned:
@echo off & setlocal enableextensions
set var=This*Is*A*String*
echo %var%
>"%temp%\tmp$$$.vbs" echo WScript.Echo Replace ("%var%", "*"," ")
for /f "delims=" %%a in ('
cscript //nologo "%temp%\tmp$$$.vbs"') do set var=%%a
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
echo %var%
endlocal & goto :EOF
C:\_D\TEST>CMDFAQ.CMD
This*Is*A*String*
This Is A String
>Timo Salmi wrote:
>> Fine tuned:
>
>http://www.netikka.net/tsneti/info/tscmd179.htm
Timo,
perhaps this line can also be fine tuned "Escaping with a backslash would
work" to read "Adding a backslash or other character would work"
As the backslash isn't an escape character in cmd then it's a little bit
misleading for those that may consider that it *is* an escape character
(and it is in SED etc).
> perhaps this line can also be fine tuned "Escaping with a backslash would
> work" to read "Adding a backslash or other character would work"
Thanks for the tip! However, the latter part "or other character" is not
the case. But I'll indeed at least rethink about the wording.
> As the backslash isn't an escape character in cmd then it's a little bit
> misleading for those that may consider that it *is* an escape character
> (and it is in SED etc).
Depending on the circumstances there are three escape characters in
command line programming: ^ % and \ as covered in
http://www.netikka.net/tsneti/info/tscmd047.htm
>> perhaps this line can also be fine tuned "Escaping with a backslash would
>> work" to read "Adding a backslash or other character would work"
>
>Thanks for the tip! However, the latter part "or other character" is not
>the case. But I'll indeed at least rethink about the wording.
Wouldn't replacing \ with ? do the same? Or +?
@echo off & setlocal enableextensions
set var=This+*is+*a+*string
echo %var%
echo %var:+*=-%
endlocal & goto :EOF
>> As the backslash isn't an escape character in cmd then it's a little bit
>> misleading for those that may consider that it *is* an escape character
>> (and it is in SED etc).
>
>Depending on the circumstances there are three escape characters in
>command line programming: ^ % and \ as covered in
> http://www.netikka.net/tsneti/info/tscmd047.htm
I read the entry but you'll note that \ is an escape character in GAWK and
not in CMD.
Yes, you are right, I was wrong. Or X, for that matter.
> I read the entry but you'll note that \ is an escape character in GAWK and
> not in CMD.
You might have missed the findstr case in the said
>>> As the backslash isn't an escape character in cmd then it's a little bit
>>> misleading for those that may consider that it *is* an escape character
>>> (and it is in SED etc).
>>
>>Depending on the circumstances there are three escape characters in
>>command line programming: ^ % and \ as covered in
>> I read the entry but you'll note that \ is an escape character in GAWK and
>> not in CMD.
>
>You might have missed the findstr case in the said
>http://www.netikka.net/tsneti/info/tscmd047.htm
Findstr also uses REGEXP but CMD does not - you can't use \ as an escape
character without using an executable.
You mentioned "command line programming" above and in that sense when using
findstr, sed, gawk, etc then \ is an escape character.
Yes. The difference between findstr vs. sed/gawk being, however, (even
if all executables) is that findstr in part of the native XP... command
line repertoire always available to an XP user. Thus, I would not
have claimed \ as one of the escape command line programming characters
if it would have been limited to sed/gawk only. I think that we now have
converged in this.
>How do I replace all asterixes (or "*") in a string in commandline or
>batch?
I think I should point out that an asterix is a small gaulish warrior.
The character commonly used in computer languages to indicate
multiplication is an asterisk.
--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.