代码之家  ›  专栏  ›  技术社区  ›  leiseg

使用扩展变量的for循环中PowerShell CLI中缺少终止符

  •  1
  • leiseg  · 技术社区  · 10 月前

    我想使用for循环仅替换文件中字符串的第二个匹配项。为了实现这一点,我使用了PowerShell CLI命令,该命令在 for 循环。

    现在,由于我必须迭代中定义的多个文件 %files% 我用 for /f "tokens=1" 将文件1与文件2分开,因为我想替换的两个字符串都在文件1中。

    这就是 对于 我使用的循环:

    for /l %%a in (1,1,2) do (
        for /f "tokens=1" %%b in ("!files!") do (
            set "file=%apb%\%%~b"
            echo !string[%%a]! --^> !replace[%%a]!
            rem Use PowerShell to replace only the second occurrence of a match, here `$matches[1]`.
            PowerShell -NoLogo -NoProfile -Command ^
                "$file = '!file!';" ^
                "$string = '(?m)^!string[%%a]!=.*';" ^
                "$content = Get-Content -Raw -Encoding UTF8 $file;" ^
                "$matches = [regex]::Matches($content, $string);" ^
                "if ($matches.Count -ge 2) {" ^
                "   $stringTwo = $matches[1];" ^
                "   $stringTwoPosition = $stringTwo.Index;" ^
                "   $stringTwoLength = $stringTwo.Length};" ^
                "Set-Content -NoNewLine $file -Value $content.Remove($stringTwoPosition, $stringTwoLength).Insert($stringTwoPosition, '!string[%%a]!=!string[%%a]!')"
        )
    )
    

    我的问题 对于 循环返回以下错误:

    The string is missing the terminator: '.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
    

    不过,所有终止符都已设置。我在某处读到,扩展变量可能会导致PowerShell CLI命令出现问题,但我不知道如何绕过扩展变量并获得我想要的结果。

    我试着把价值观称为 !string[%%a]! !replace[%%a]! 通过非展开变量 %stringAlias% %replaceAlias% 这不起作用。

    这是为期末考试做准备的片段的其余部分 对于 循环:

    @echo off
    setlocal EnableDelayedExpansion
    rem Set target files.
    set "files=Engine\Config\BaseEngine.ini APBGame\Config\DefaultEngine.ini"
    rem Initialize variables.
    set "replace="
    set "string="
    call :subroutine.ping_optimization "%files%"
    if !errorlevel! equ 0 (
        set "count=1"
        for %%a in (
            "1.0"
            "5.0"
            rem ...
        ) do (
            set "replace[!count!]=%%~a"
            set /a "count+=1"
        )
    )
    if !errorlevel! equ 1 (
        set "count=1"
        for %%a in (
            "0.001"
            "0.001"
            rem ...
        ) do (
            set "replace[!count!]=%%~a"
            set /a "count+=1"
        )
    )
    set "count=1"
    for %%a in (
        "AckTimeout"
        "KeepAliveTime"
        rem ...
    ) do (
        set "string[!count!]=%%~a"
        set /a "count+=1"
    )
    rem for loop causing issues goes here...
    
    1 回复  |  直到 10 月前
        1
  •  2
  •   mklement0    10 月前

    许多不幸的行为之一 cmd.exe (批处理文件的解释器)是命令的行为不同 里面 (...) -封闭的身体 for /f 循环 .

    具体而言 内线 ^ 人物在 "$string = '(?m)^!string[%%a]!=.*';" ^ -尽管如此 内部A "..." 一串 -令人费解 逐字使用,需要转义为 ^^ .

    也就是说,更换线路
    “$string='(?m)^!string[%%a]!=.*';”^ 在您的问题代码中
    "$string = '(?m)^^!string[%%a]!=.*';" ^ 应该能解决你的问题。