在.bat(批处理文件)中查找和替换导致未知错误的字符串

Posted

技术标签:

【中文标题】在.bat(批处理文件)中查找和替换导致未知错误的字符串【英文标题】:Find and Replace String causing unknown error in .bat (batch file) 【发布时间】:2022-01-09 17:07:41 【问题描述】:

我正在尝试使用批处理替换 .yml 文件中的一些文本。

我的代码:

@echo off
if not defined in_subprocess (cmd /k set in_subprocess=y ^& %0 %*) & exit )
setlocal enableextensions 

set jruby="%~dp0jruby\bin\jruby"
set someDir="%~dp0..\test\test2"

cd %someDir%
copy /y file.yml test_file.yml > NUL
for /f "tokens=2*" %%i in (file.yml) do @set "password=%%i"
echo Your password --- %password% --- will now be encrypted due to security reasons...

%jruby% -S run_file.rb 

for /f "delims=" %%x in (some_file.rb) do set some_key=%%x

FOR /F "tokens=* USEBACKQ" %%F IN (`%jruby% -S encrypt_property_for_yaml encrypt %some_key% %password%`) DO (
SET encrypted_pw=%%F
)
echo Random 32-Bit encryption key created: %some_key%
echo Password was encrypted to: %encrypted_pw%
echo.
echo Encrypted password will be saved in file.yml file...

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

由于这个代码块而发生错误

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

整个过程完美无缺,但是一旦我到达最后一个发生实际替换的FOR-BLOCK,我总是会收到以下错误:

! was unexpected at this time

一开始我以为是因为 echo 缺少右括号,但这仍然会导致同样的错误。

*旁注:我用来查找和替换的方法最初来自here

有趣的是,当我在一个完全独立的 .bat 文件中运行相同的代码时,它可以完美运行,但是当我将它与当前的批处理文件(包括其他代码)一起使用时,我总是会遇到同样的错误。我尝试使用set 而不是>>"%databaseFile%" echo(!line:%search%=%replace%!

我尝试谷歌搜索,发现一些类似的情况与延迟扩展有关,但我似乎无法让 FIND and REPLACE 工作。

【问题讨论】:

显示我在您的示例中定义的 “加密密码” 示例。 @Gerhard 是这样的:ENC(qQU35msnA699PH9RX18XYQ==) 我检查了回声关闭,它被正确分配给变量 你有问题。您需要将右括号转义为^) 代码块将其视为自身的右括号。 @Gerhard 你的意思是 ENC(qQU35msnA699PH9RX18XYQ==) 上的右括号?我在 SET encrypted_pw=%%F 处分配它,我是否在 %%F 之后添加 ^)? 好的,所以直接在set "replace=%encrypted_pw%" 之前执行set "encrypted_pw=%encrypted_pw:)=^)%" 我还必须警告你,如果你的密码包含!,它会因为delayedexpansion 而删除它,所以也要考虑这一点。不过有办法解决这个问题。 【参考方案1】:

密码包含关闭括号,被视为代码块的关闭。你需要逃避每个)的出现

在下面的代码中,我添加了替换部分:

set "encrypted_pw=%encrypted_pw:)=^)%"
set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace%!
    endlocal
)
pause

另外,更好的是,你可以让它更短,让它成为循环中替换本身的一部分:

set "replace=%encrypted_pw%"
set "databaseFile=file.yml"
set "search=%password%"

for /f "delims=" %%i in ('type "%databaseFile%" ^& break ^> "%databaseFile%" ') do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    >>"%databaseFile%" echo(!line:%search%=%replace:)=^)%!
    endlocal
)
pause

【讨论】:

谢谢,完美运行! :)

以上是关于在.bat(批处理文件)中查找和替换导致未知错误的字符串的主要内容,如果未能解决你的问题,请参考以下文章

bat中替换中文字符串

Bat如何替换文件内容?

Bat如何替换文件内容?

批处理bat查找记事本文件中指定字符串并替换为回车,也就是换行,最后保存到记事本中

使用 .bat 文件在目录中包含的多个文件中查找和替换字符串

bat命令怎么替换里面的字符串?