I need to map or replace the asterisk * in an environment variable using only native Windows commands. Is it possible?

I am trying to remove an asterisk from a string of environment variables, but I cannot do it.

I am creating an m3u file based on search strings, so for example, if I want to make an m3u file containing each song with the word love, I would enter:

m3u *Love* 

And m3u.bat will create a file:

 xLovex.m3u 

But the usual character replacement method does not work with an asterisk. (Although I do not have this problem with a question mark.)

 set nam=%nam:*=x%.m3u 

Instead, a file name is created.

 x.m3u 
+5
source share
4 answers

The simple answer is no.

The problem you are facing is that the asterisk * is a special character when used with the search and replace method SET. It matches multiple characters in a limited but useful way. You can find out about it here .

The difficult answer is yes !

I will give you two solutions. One incomplete solution, but elegant, the other complete and not elegant.

Both methods will look for * and replace it with x.
Both methods will search and modify the following line:

 *love* 

The first method that comes to mind is to use the FOR / L operator, which requires you to know how many characters the environment variable contains.

:: Major Edit ::

I thought I knew the different lines of the maximum sizes of the environment variables, but dbenham took me to school, showed me the function of the stroke length , and at the same time completely changed my mind about the two solutions that I Presentation.

With the exception of the Windows 95/98 / ME limit, the maximum size of the environment variable is 256 characters. It seems that all versions of Windows using CMD.EXE have a limit of 8,192 characters, which is significantly lower than what is suggested in the documentation.

Both versions require delayed expansion of the environment variable, but for two different reasons. One, because I work inside a FOR statement. Another, because you cannot put the% pair in another% pair, because the shell matches the second% that it encounters with the first% that it encounters, but we need to use the variable inside another variable expression. (You'll see.)

This solution uses the strLen function (on line 3) from DosTips.com, which can be found here . Just put it in a file called strLen.bat and marvel at the speed!

Solution 1: (FOR / L Solution) :: Preferred Solution ::

 setlocal ENABLEDELAYEDEXPANSION set nam=*love* rem calling strLen call :strLen nam len for /l %%x in (0,1,%len%) do if not "!nam:~%%x,1!"=="" if "!nam:~%%x,1!"=="*" ( set /a plusone=%%x+1 for /l %%y in (!plusone!, 1, !plusone!) do ( set nam=!nam:~0,%%x!x!nam:~%%y! ) ) echo %nam% ENDLOCAL 

I think this is a quick and elegant solution. It can be accelerated by adding the contents of strLen.bat to the routine, but I did not want to confuse the author.

If for some reason you do not want to use strLen, then the next quick method is likely to use the GOTO loop.

Solution 2: (Go to solution)

 setlocal ENABLEDELAYEDEXPANSION set nam=*love* set num=0 :loop set /a plusone=%num%+1 if "!nam:~%num%,1!"=="*" set nam=!nam:~0,%num%!x!nam:~%plusone%! set /a num=%num%+1 if not "!nam:~%num%,1!"=="" goto :loop echo %nam% EndLocal 

Special thanks to dbenham for pointing to the strLen function. It works faster than any batch function is entitled!

+10
source

Another solution to this problem is to use the PowerShell replacement command in your batch script.

 set var=*Love* echo %var%>var.txt | powershell -command "((get-content var.txt) -replace '[\x2A]','x') -replace '.{1}$' | set-content var.txt" set /p var=<var.txt set var=%var%.m3u echo %var% 

In the above code, the second line

  • writes your string to a text file
  • calls the PowerShell command to get the contents of this file
  • replaces the * character with zero
  • overwrites the text file with the new value

Once this is done, you will read the value back into your variable.

For a further explanation of the replacement command, the first single quotes are what you are looking for. We use square brackets to designate the character * as a hexadecimal character (\ x2A is the hexadecimal value for *). After the comma, the second set of single quotes does not contain a value, so the desired object is deleted. To avoid the space between xLovex and .m3u, we must use -replace '. {1} $ 'before writing the result to a text file.

Once you are done with the text file, enter the line to delete it.

 if exist var.txt del var.txt 
+1
source

Although some very good and reliable methods have already been described here, I would still like to add another option for completion.

This is not as good as the other options, but I personally use it in some cases when I would like to keep the code clean and where I know that this will be enough:

This works by using for/f delims to cut the string into two parts, which then join together, getting rid of * in the process:

 for /f "tokens=1,* delims=*" %%a in ("a*b") do (set string=%%a%%b) >>> string=ab 

Obviously, the disadvantage of this is that it can only be used to remove one *.

To remove more, we can simply use more tokens ...

 for /f "tokens=1-3,* delims=*" %%a in ("a*b*c*d") do (set string=%%a%%b%%c%%d) >>> string=abcd 

... or we can put the first line in for/l -loop:

 setlocal enableDelayedExpansion set string=a*b*c*d for /l %%a in (1, 1, 3) do ( for /f "tokens=1,* delims=*" %%b in ("!string!") do (set string=%%b%%c) ) >>> string=abcd 

It should also be noted that in delims you can define more than one character, and they will all be deleted immediately:

 for /f "tokens=1,* delims=+-*/" %%a in ("a*-/+b") do (set string=%%a%%b) >>> string=ab 
0
source

See this answer , and set-ast.bat , I want to put set-ast nam "x" in your file where necessary.

set-ast accepts <variable-to-modify> <string-to-replace-asterisks-with> parameters

-1
source

All Articles