首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >批量替换!-sign

批量替换!-sign
EN

Stack Overflow用户
提问于 2015-06-14 18:53:58
回答 2查看 199关注 0票数 2

我正在尝试删除变量中的字符!

代码语言:javascript
复制
setlocal enableextensions enabledelayedexpansion 
set filename=!filename:!=_! 

我已经尝试用^来摆脱它,但这不起作用。

代码语言:javascript
复制
Set filename=!filename:^!=_!

怎样才能去掉变量中的!-sign?

EN

回答 2

Stack Overflow用户

发布于 2015-06-15 01:27:59

使用正常扩展时不能替换%。您必须在insntead:!var:%%=_!中使用延迟扩展

同样,使用延迟扩展时不能替换!。您必须改用正常扩展:%var:!=_%

但是,如果您的变量可能包含^&|><以及引号等有害字符的混合,那么这可能是一个问题。例如,没有一步方法可以替换以下字符串中的!"This & that" & the other thing!

诀窍是分阶段进行替换,主要使用延迟扩展,其中一个替换使用正常扩展。

1)延迟扩展-将"转换为""

2)正常扩容-将!转换为replacement。由于所有引号都是双引号,扩展前后的外引号现在可以保证保护所有有害字符

3)延迟扩展-将""转换回"

代码语言:javascript
复制
@echo off
setlocal enableDelayedExpansion
set "var="This ^& that" & the other thing^!"
echo before: !var!

set "var=!var:"=""!"
set "var=%var:!=_%"
set "var=!var:""="!"

echo  after: !var!

-输出--

代码语言:javascript
复制
before: "This & that" & the other thing!
 after: "This & that" & the other thing_

但是您要处理的是文件名,这可以使问题变得更简单:-)

文件名可以包含有害字符&^,但不能包含引号。您可以将引号放在文件名(或路径)内的任何位置,这样可以保护有害字符。但是,当操作系统在磁盘上存储或查找文件时,引号会被删除。

因此,我通常会确保我的文件名和路径变量不包含引号。这样就可以安全地简单地使用:

代码语言:javascript
复制
set "filename=%filename:!=_%"

Oops -我刚刚才读到问题评论,看到这是在循环中!

替换发生在循环中这一事实使事情变得复杂,因为正常的扩展看不到循环中定义的值。

请注意,在展开FOR变量时必须关闭延迟展开,否则将损坏文件名中的!

最简单的解决方案是使用CALL来获得额外的扩展:

代码语言:javascript
复制
@echo off
setlocal disableDelayedExpansion
for %%F in (*) do (
  set "file=%%F"
  call set "file=%%file:!=_%%"
  setlocal enableDelayedExpansion
  echo file=!file!
  endlocal
)

如果您正在执行其他需要延迟扩展的操作,则需要在正常扩展替换表达式中对!进行转义,因为延迟扩展发生在调用之前。(谢谢jeb)。

下面是一个删除了^&的示例。

代码语言:javascript
复制
@echo off
setlocal disableDelayedExpansion
for %%F in (*) do (
  set "file=%%F"
  setlocal enableDelayedExpansion
  set "file=!file:^=_!"
  set "file=!file:&= and !"
  call set "file=%%file:^!=_%%"
  echo file=!file!
  endlocal
)

尽管我可以在删除!之后简单地启用延迟扩展。那么就不需要逃脱了。

票数 4
EN

Stack Overflow用户

发布于 2015-06-14 19:31:19

目前我脑海中唯一浮现的是子例程和隧道:

代码语言:javascript
复制
@echo off

set "line=!---!asd!asd!"

setlocal enableDelayedExpansion
    echo !line!
    call :subr "!line!" line
    echo !line!
endlocal
exit /b %errorlevel%

:subr
setlocal disableDelayedExpansion
    set "string=%~1"
    set "res=%string:!=$%"
endlocal && (
    set "%~2=%res%"
)

只需在脚本末尾定义如下所示的子例程,并在for循环中调用它

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30828500

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档