anandr
I came into trouble with the Variable Edit/Replace syntax of the SET command (https://ss64.com/nt/syntax-replace.html).
My batch script receives file mask as a parameter.
While processing thoe files I need to save a log to file, whose name contains the mask.
But "*" and "?" are not allowed in file name and I'm trying to replace "*" with "_all_" string.
I do this:
Code: Select all
::here I store the mask
set FileMask="%~1"
::here I try to modify the mask to put it into log file name
set SuggestedFileName=%FileMask:*=_all_%
Code: Select all
=_all_% was unexpected at this time.
How it is possible to replace "*" itself?
Thanks
P.S.
These lines do not work either:
Code: Select all
set SuggestedFileName=%FileMask:^*=_all_%
call set SuggestedFileName=%%FileMask:*=_all_%%
----------------------------
#2 11 Aug 2010 20:05
RG
Sorry,
When "str1" begins with an asterisk it indicates that it will match everything from the beginning of the expanded output to the first occurrence of the remaining portion of str1.
For example, the line below would work if your mask is always of the format: FileName.*, which is probably not much help other than an explanation.
Code: Select all
set SuggestedFileName=%FileMask:.*=._all_%
Windows Shell Scripting and InstallShield
----------------------------
#3 11 Aug 2010 23:23
RG
This will work although it will not catch multiple consecutive *
Code: Select all
set SuggestedFileName=
call :Replace "%~1"
echo.SuggestedFileName=%SuggestedFileName%
goto :eof
:Replace
rem %1=String
rem Need next line to handle leading *
for /F "tokens=* delims=*" %%a in ("%~1") DO if not "%~1"=="%%a" set SuggestedFileName=_all_%SuggestedFileName%
for /F "tokens=1* DELIMS=*" %%a in ('echo.%~1') do (
(CALL set SuggestedFileName=%SuggestedFileName%%%a)
rem Line below will also handle trailing * if needed. Be careful of that if you simplify it.
if not "%%a%%b"=="%~1" call set SuggestedFileName=%SuggestedFileName%_all_& call :Replace "%%b"
)
goto :eof
Windows Shell Scripting and InstallShield
----------------------------
#4 12 Aug 2010 10:03
bluesxman
Another method.
Code: Select all
@echo off
set "in.string=qwertyuiop*asdfghjkl"
set "replace=*"
set "with=_all_"
set "out.string="
REM current position within IN.STRING
set i=0
REM length of REPLACE string
set L=1
set in.string
call :loop
set out.string
pause
goto :EOF
:loop
REM grab the next set of characters in the string
call set "char=%%in.string:~%i%,%L%%%"
REM if they are blank, we've reached the end of the string
if "%char%" EQU "" goto :EOF
if "%char%" EQU "%replace%" (
REM if they match the REPLACE string, add the WITH string to OUT.STRING
set "out.string=%out.string%%with%"
) ELSE (
REM otherwise just add them to OUT.STRING
set "out.string=%out.string%%char%"
)
REM increment our position in IN.STRING for the next loop
set /a i+=L
call :loop
cmd | *sh | ruby | chef
----------------------------
#5 12 Aug 2010 16:14
jumper
Code: Select all
@echo off&setlocal enabledelayedexpansion
set "in.str=*qwe*rt**yuiop*asdfghj*kl*"
set in.str
set ou.str=&for /f "tokens=1* delims=][" %%a in ('
"%comspec% /u /cecho:"%in.str%"|more|find /n /v """
') do (set "b=%%b"&if "%%b"=="*" (set $=_all_) else set "$=%%b"
set ou.str=!ou.str!!$!)
set "ou.str=%ou.str:~1,-1%"
set ou.str
pause
goto:eof
----------------------------
#6 12 Aug 2010 16:50
bluesxman
Nice work jumper.
An interesting method for breaking the string into single characters -- took me a while to figure out what you're doing there.
Might I suggest the following refinements to allow for file names containing "&", "[" or "]"?
Code: Select all
@echo off
set "in.str=*qw!e*rt**yu&iop*a[[[s][]dfghj*kl*"
set in.str
set ou.str=&for /f "tokens=* delims=" %%b in ('
%comspec% /u /cecho:"%in.str%" ^|more ^|find /v """"
') do (
if "%%b" EQU "*" (
call set "ou.str=%%ou.str%%_all_"
) else (
call set "ou.str=%%ou.str%%%%b"
)
)
set ou.str
pause
goto:eof
----------------------------
#7 12 Aug 2010 18:19
jumper
Re: Does anyone know how to replace a * symbol in a string?
thank's bluesxman your code is better,bluesxman wrote:
Nice work jumper.
An interesting method for breaking the string into single characters -- took me a while to figure out what you're doing there.
Might I suggest the following refinements to allow for file names containing "&", "[" or "]"?
Code: Select all
@echo off set "in.str=*qw!e*rt**yu&iop*a[[[s][]dfghj*kl*" set in.str set ou.str=&for /f "tokens=* delims=" %%b in (' %comspec% /u /cecho:"%in.str%" ^|more ^|find /v """" ') do ( if "%%b" EQU "*" ( call set "ou.str=%%ou.str%%_all_" ) else ( call set "ou.str=%%ou.str%%%%b" ) ) set ou.str pause goto:eof
Another method with SED:
Code: Select all
@echo off
Set "Path=X:\Program Files\GnuWin32\bin;%path%" # set environment variable
set "in.str=*qw!e*rt**yu&iop*a[[[s][]dfghj*kl*" # your string
set in.str
echo "%in.str%" | sed "s=^\x22\|\x22.$==g;s=\x2a=_all_=g"
Last edited by jumper (12 Aug 2010 18:19)
----------------------------
#8 13 Aug 2010 11:56
anandr
Thank you, jumper and bluesxman!
That is amazing, guys!
Could you, please, explain why this command breaks string into characters?
Code: Select all
%comspec% /u /cecho:"%in.str%" ^|more
Does this mean that "more" can not handle unicode characters properly and treats zero-characters as EndOfLine?
Whatever it is you are incredible.
I'm taking off my hat to you!
Everything will be OK at the end. If it is not OK -- it is not the end.
----------------------------
#9 13 Aug 2010 12:46
bluesxman
It looks that way to me.anandr wrote:
Does this mean that "more" can not handle unicode characters properly and treats zero-characters as EndOfLine?
It's certainly an interesting quirk. I hope to exploit it frequently in future now that jumper has brought it to my attention!
cmd | *sh | ruby | chef
----------------------------
#10 14 Aug 2010 17:49
RG
WOW! That is really clever jumper. And thanks for the extra touch bluesxman.
Life just got easier! I will use that a lot! Sure beats my solution, which was plenty of work and was not bullet proof.
Thanks Guys.
Windows Shell Scripting and InstallShield
----------------------------
#11 14 Aug 2010 18:44
Simon Sheppard
Its an interesting technique, but if I feed it some real unicode characters strange conversions happen:
Code: Select all
C:\>%comspec% /c echo £¥ƒ*?$¢|more
£¥ƒ*?$¢
C:\>%comspec% /u /c echo £¥ƒ*?$¢|more
ú
Ñ
Æ☺*
¼ $
ó
----------------------------
#12 14 Aug 2010 19:15
carlos
I think that you can improve line.
From:
Code: Select all
%comspec% /u /cecho:"%in.str%" ^|more
Code: Select all
%comspec% /u /d /x /v:off /cecho:"!in.str!" ^|more