我需要匹配或替换星号*在批处理环境变量只使用原生的Windows命令。 这可能吗?(I need

2019-06-26 14:19发布

我试图从环境变量字符串中删除一个星号,但似乎无法做到这一点。

我在周围搜索字符串基于创建m3u文件,所以比如我,如果我想使含在它与爱字每首歌曲的m3u文件,我可以输入:

m3u *Love*

而m3u.bat将创建文件:

xLovex.m3u

但用字符的常规方法不带星号的工作。 (虽然我没有问号这个问题。)

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

相反,创建文件名

x.m3u

Answer 1:

最简单的答案是否定的。

您所遇到的问题,从一个事实,即星号*是一个特殊字符与SET用于搜索和替换方法时造成的。 它的多个字符匹配在一个有限的,但仍然有用,方式。 您可以了解这里 。

硬答案是肯定的

我将为您提供两种解决方案。 一个不完整的解决方案,但高贵,其他完整和inelegent。

这两种方法都将搜索*,并用X代替它。
这两种方法都将搜索和修改以下字符串:

*love*

想到的第一种方法是使用“FOR / L”语句,并要求你知道有多少个字符长的环境变量。

::主要编辑::

我想我知道环境变量的不同最大尺寸字符串,但dbenham采取了我去学校,我所示的踢在最落后的长度功能 ,并在平均时间彻底扭转我的两个解决方案,我的意见呈现。

除了为Windows 95/98 / ME限制的256个字符的最大环境变量的大小。 看来,使用CMD.EXE所有版本的Windows有8,192个字符的限制,远低于文档建议什么。

两个版本都需要延迟环境变量扩展,而是两个不同的原因。 之一,因为我是一个FOR语句内运行。 另外,因为你不能把一双%其他%对内因为命令处理器相匹配的第二%,它遭遇到它遇到的第一个,但我们需要使用另一个变量表达式中的变量。 (你会看到的。)

该解决方案使用strlen函数(第3行)从DosTips.com,可以发现在这里 。 只是拍它变成一个名为strLen.bat和它的速度感到惊讶文件!

解决方案1:(FOR / L溶液)::优选方案::

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

我认为这是一个快速而优雅的解决方案它可以通过增加strLen.bat的内容到程序被加快,但我想没有混乱,给作者。

如果由于某种原因,不希望使用strlen,那么下一个最快的方法可能会使用一个GOTO循环。

解决方案2:(后藤溶液)

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

特别感谢dbenham您指出的strlen函数。 它比任何基于批处理功能更快的拥有权!



Answer 2:

到了上述问题的另一个解决方案是使用PowerShell的你的批处理脚本中替换命令。

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%

在上面的代码中,第二线

  • 写你的字符串转换成文本文件
  • 调用PowerShell命令来获取文件的内容
  • 替换空字符*
  • 覆盖与新值的文本文件

一旦做到这一点,你读值回你的变量。

为了进一步说明替换命令,第一个单引号是你要搜索的内容。 我们使用方括号标识*字符作为十六进制字符 (\ X2A是十六进制值*)。 逗号后,第二组单引号的不包含任何值,使得搜索的对象被删除。 为了防止xLovexm3u格式之间的空间,我们有结果写入文本文件之前使用-replace“ {1} $”。

一旦你完成了文本文件来完成,输入一行将其删除。

if exist var.txt del var.txt


Answer 3:

虽然已经有一些很好的和强大的方式在这里解释,我还是想添加另一种选择完成的缘故。

它并不像其他选项一样好,但我个人用它在某些情况下,我想保持代码干净,我知道,这将足够了:

它的工作方式是通过使用for /fdelims字符串切成两个部分,然后将它们放回一起,摆脱在这个过程中*的:

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

>>> string=ab

显然,这样做的缺点是,它只能用来删除一个*。

去除更多的,我们可以只使用更多令牌...

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

>>> string=abcd

......或者我们可以把第一行中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

另外要注意的是,你可以在定义多个字符delims ,他们都将立即被移走:

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

>>> string=ab


Answer 4:

见这个答案 ,并与设置ast.bat你会想要把set-ast nam "x"在文件中需要的地方。

set-ast取参数<variable-to-modify> <string-to-replace-asterisks-with>



文章来源: I need to match or replace an asterisk * in a batch environmental variable using only native Windows commands. Is this possible?