0

我需要从一个目录中读取所有文本文件,然后在每个文件中用另一个字符串(替换为)替换某种类型的字符串(在具有“volumelabel”的行中)。以下是代码片段:

for /r %%g in (*.txt) do (
 set filename=%%~nxg
 for /F "tokens=3 delims=<>" %%i in ('findstr "volumelabel" !filename!') do (
  set tobereplaced=%%i
 )
 echo !filename! has !tobereplaced! to be replaced by %replacewith%
 for /F "tokens=*" %%a in (!filename!) do (
  set str=%%a
  set str=!str:!tobereplaced!=%replacewith%!
  echo !str!>>new!filename!
 )
)

现在我面临的问题是它只tobereplaced(字面上)在新文件的每一行中打印

set str=!str:!tobereplaced!=%replacewith%!
echo !str!>>new!filename!

使用并打印tobereplaced=replacewith(值)时

set str=%str:!tobereplaced!=%replacewith%%
echo !str!>>new!filename!

用来。有人能帮我吗?

4

1 回答 1

1

最不复杂的解决方案(以我的拙见)是使用子程序来set str. 超过一级的延迟扩张往往会导致严重的脑损伤。哦,您可能可以set str通过执行以下操作来修复您的线路

call call call set str=%%%%str:%%tobereplaced%%=%replacewith%%%%%

...或类似的。明白我说的脑损伤是什么意思吗?很难遵循递归。

所以这是我对解决方案的建议。我还解决了另一个或两个潜在问题。由于您正在对 *.txt 进行递归搜索,因此我使for循环能够处理它们在子目录中找到的任何文本文件。我还没有对此进行测试,所以如果您遇到任何奇怪的错误,请告诉我。

@echo off
setlocal enabledelayedexpansion
set replacewith=whatever

for /r %%g in (*.txt) do (
    set newfile=%%~dpng.new%%~xg
    for /F "tokens=3 delims=<>" %%i in ('findstr "volumelabel" "%%g"') do (
        set "tobereplaced=%%i"
        echo %%~nxg has !tobereplaced! to be replaced by %replacewith%

        rem combining your for loops this way makes the second only fire if the first is true
        rem using "findstr /n" in your for loop preserves blank lines
        for /F "delims=" %%a in ('findstr /n "^" "%%g"') do (

            rem ...but you have to strip off the line numbers
            set "str=%%a" && set "str=!str:*:=!"

            rem "call :repl" to work around the delayed expansion conundrum
            call :repl "!str!" "!tobereplaced!" "%replacewith%" str
            echo !str!>>!newfile!
        )
    )
)
goto :EOF

:repl <line> <find> <replace> <var>
setlocal enabledelayedexpansion
set "line=%~1"
set "line=!line:%~2=%~3!"
set "%4=%line%"
goto :EOF

警告:如果您的文本文件包含感叹号、等号或克拉,它们可能不会进入 textfile.new.txt。


对于它的价值,如果我在你的位置,而不是使用批处理文件,我可能会使用sed(二进制文件应该是你所需要的)。你甚至不需要脚本。你可以像这样作为一个班轮来做:

for /r %I in (*.txt) do sed -r "s/volumelabel/replacement/ig" "%I" > "%~dpnI.new%~xI"

顺便说一句,有关这种符号help for的解释,请参阅最后几页。%~dpnI

于 2013-03-12T12:41:32.773 回答