Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我需要仅使用本机Windows命令匹配或替换批处理环境变量中的星号*。这可能吗?_Windows_Batch File_Replace_Cmd - Fatal编程技术网

我需要仅使用本机Windows命令匹配或替换批处理环境变量中的星号*。这可能吗?

我需要仅使用本机Windows命令匹配或替换批处理环境变量中的星号*。这可能吗?,windows,batch-file,replace,cmd,Windows,Batch File,Replace,Cmd,我试图从环境变量字符串中删除星号,但似乎无法做到这一点 我正在创建一个基于搜索字符串的m3u文件,因此,例如,如果我想制作一个m3u文件,其中包含每首歌曲中的“爱”一词,我会输入: m3u *Love* m3u.bat将创建以下文件: xLovex.m3u 但是用星号替换字符的常规方法不起作用。(虽然我对问号没有问题。) 而是创建文件名 x.m3u 简单的答案是否定的 您遇到的问题源于这样一个事实,即星号*与SET search and replace方法一起使用时是一个特殊字符。它以有限

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

我正在创建一个基于搜索字符串的m3u文件,因此,例如,如果我想制作一个m3u文件,其中包含每首歌曲中的“爱”一词,我会输入:

m3u *Love*
m3u.bat将创建以下文件:

xLovex.m3u
但是用星号替换字符的常规方法不起作用。(虽然我对问号没有问题。)

而是创建文件名

x.m3u
简单的答案是否定的

您遇到的问题源于这样一个事实,即星号*与SET search and replace方法一起使用时是一个特殊字符。它以有限但仍然有用的方式匹配多个字符。你可以了解这一点

答案是肯定的

我将为您提供两种解决方案。一个是不完整的解决方案,但很简单, 另一种是完全的和不自然的

这两种方法都将搜索*并将其替换为x。
这两种方法都将搜索和修改以下字符串:

*love*
想到的第一种方法是使用“FOR/L”语句,并要求您知道环境变量的长度

::主要编辑::

我原以为我知道环境变量的各种最大值字符串,但德本汉带我去了学校,给我看了一本书,同时完全颠倒了我对我提出的两种解决方案的看法

除了Windows 95/98/ME限制的256个字符的最大环境变量大小之外。似乎所有使用CMD.EXE的Windows版本都有8192个字符的限制,远远低于文档中的建议

两个版本都需要延迟环境变量扩展,但有两个不同的原因。一个是因为我在FOR语句中操作。另一个原因是您无法将%pair放在另一个%pair中,因为命令处理器将遇到的第二个%与遇到的第一个%相匹配,但我们需要在另一个变量表达式中使用一个变量。(你会看到的。)

此解决方案使用DosTips.com中的strLen函数(第3行),可以找到该函数。只需将其放入一个名为strLen.bat的文件中,并对其速度感到惊讶

解决方案1:(适用于/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:(转到解决方案)

特别感谢dbenham指出strLen函数。它的工作速度比任何基于批处理的函数都要快

请参见,并且使用,您将希望在需要的地方将
设置为“x”


set ast
接受参数

虽然这里已经解释了一些非常好和健壮的方法,但为了完成,我仍然想添加另一个选项

它不如其他选项好,但我个人在某些情况下使用它,我希望保持代码干净,并且我知道它足够:

它的工作方式是使用
for/f
delims
将字符串切割成两部分,然后再将它们放回一起,在过程中去掉*:

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
。。。或者我们可以将第一行放入/l的
循环中:

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

上述问题的另一个解决方案是在批处理脚本中使用PowerShell replace命令

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%

这是一种不遍历字符串的所有字符的方法,但它使用在某个字符(序列)的每次出现时分割字符串。实际功能打包到一个子例程中以便于重用,因此以下脚本的主要部分仅包含一些要测试的代码:

@echo关闭
setlocal EnableExtensions DisableDelayedExpansion
::这是用于测试和演示的脚本代码的主要例程:
rem//要测试的一些示例文本的定义(注意,`%%`变成了一个文本'%`):
设置“数据=一些文本,”^&“&;0'@%%~\\\`$:通配符**卡片*?。re=+([{parens}])-^/equal==to=!\
回音/
调用:REPL_CHAR文本数据“*”“?”
setlocal EnableDelayedExpansion
回声(在:!数据!
回声(输出:!文本!
回音/
回声(在:!TEXT!
调用:REPL_CHAR TEXT TEXT“=”/“
回声(输出:!文本!
端部
端部
退出/B
:REPL_CHAR
::此函数在字符串中替换某个字符序列的每次出现
::通过另一个字符或字符串。它甚至可以正确处理字符“*`和”=`。
::用法:
::调用:REPL_CHAR ref_output_string ref_input_string val_search_CHAR val_replace_CHAR
::参数:
::ref_output_string引用(名称)变量以接收结果字符串;
::ref_input_string引用保存原始字符串的变量;如果为空
::(```),使用`ref_output_string`引用的变量;
::val_search_char要替换的单个字符;
::val_replace_char字符或字符串以替换“val_search_char”的每个序列`
::有;这甚至可能是空的;
rem//定位环境并检测是否启用延迟扩展(稍后需要):
setlocal&设置“$NDX=!”
setlocal DisableDelayedExpansion
rem//获取参数并验证它们:
s
for /f "tokens=1,* delims=+-*/" %%a in ("a*-/+b") do (set string=%%a%%b)

>>> string=ab
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%
if exist var.txt del var.txt