批处理:在字符串中查找带引号的子字符串

Posted

技术标签:

【中文标题】批处理:在字符串中查找带引号的子字符串【英文标题】:Batch: Find substring with quotes in string 【发布时间】:2022-01-10 21:46:08 【问题描述】:

我无法让它工作。我正在逐行读取 XML 文件,然后查看每一行是否包含特定标记 。找到它时,我会对其进行修改并编写所有内容回到一个文件中。 但是,我找不到标签,因为它包含引号。

@ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
....some more code....
SET dllFile=%DestPath%\%ProjectName%.dll.manifest

IF NOT EXIST "%dllFile%" (
   ECHO File %ProjectName%.dll.manifest does not exist^^!
   GOTO ERROR
) ELSE (
   ECHO Modifying %ProjectName%.dll.manifest in directory:
   ECHO %DestPath%

   REM Create a temporary file in the folder, where this batch file is being executed from
   >"temp.xml" (
      FOR /F "usebackq delims=" %%I IN ("%dllFile%") DO (
        SET "line=%%I"

        REM Insert existing line before modification
        SETLOCAL DisableDelayedExpansion
        ECHO %%I
        ENDLOCAL

        REM Find correct version number
        SET "myVariable=<assemblyIdentity name="PostDeploymentAction" version"
        IF not "!line!"=="!line:myVariable=!" (
          echo !line!
        )
        ....some more code....
       )
    )
  )

无论我使用什么转义字符,它都不会找到这个特定的行(或者它会找到每一行)。上面代码中的其他所有内容都可以正常工作 - 只有 IF not "!line!"=="!line:myVariable=!" 不能。非常感谢任何帮助。

谢谢

【问题讨论】:

为什么要分配临时变量myVariable 那是我拼命尝试解决 IF 语句中的双引号问题... 我刚刚在搜索字符串中发现了一个=-符号,这是不可能的,因为这样可以分隔搜索字符串和替换字符串…… 【参考方案1】:

使用另一种方法比较字符串:

@echo off
setlocal enabledelayedexpansion
; set "myvariable=<assemblyIdentity name="PostDeploymentAction" version"
set myvariable
for /f "delims=" %%a in (test.txt) do (
  echo "%%a"|findstr /c:"!myvariable:"=\"!">nul && (
    echo DEBUG: found %%a
    REM do something special here
  ) || (
    echo %%a
    REM write line unchanged
  )
)

(您必须使用findstr; findstr 转义双引号,使用反斜杠作为转义字符)

【讨论】:

【参考方案2】:

最后,我得到了

SET "xmlTag=<assemblyIdentity name="PostDeploymentAction"
FOR /F "usebackq delims=" %%A IN ("%dllFile%") DO (
    ECHO "%%A"|FINDSTR /c:"!xmlTag:"=\"!">nul && (
        FOR /F "tokens=2,3 delims=^=" %%B IN ("%%A") DO (
        SET version=%%C
        SET version=!version:~0,-9!
        ECHO Found PostDeploymentAction.dll version number !version!
        )
    )
)

这给了我想要的版本号。完整的 XML 行是 &lt;assemblyIdentity name="PostDeploymentAction" version="1.1.0.0" language="neutral" processorArchitecture="msil" /&gt;。第一个 FOR 循环从 XML 文件中获取整行,而第二个 FOR 获取实际版本号“1.1.0.0”。 第二个 FOR 有点奇怪,但它有效。不过,我相信还有更好的方法...

【讨论】:

也许可以考虑使用一种具有本机方法来读写 XML 的语言。 Jscript、Vbscript 和 Powershell 都是 Windows 自带的脚本语言,可以实现这一点。【参考方案3】:

顺便说一句,上面有点慢,因为文件的每一行都调用了 FINDSTR(逐行读取文件,然后用 FINDSTR 分析每一行)。 有一个更快的版本,它只对整个文件调用一次 FINDSTR,然后分析 FINDSTR 找到的返回结果。

SET "xmlTag=<assemblyIdentity name="PostDeploymentAction"
FOR /F "tokens=*" %%A in ('FINDSTR /c:^"!xmlTag:"=\"!^" ^"%dllFile%^"') DO (
    FOR /F "tokens=5 delims=^=^ " %%B IN ("%%A") DO (
       SET version=%%B
       ECHO Found PostDeploymentAction.dll version number !version:~1,-1!
    )
)

【讨论】:

以上是关于批处理:在字符串中查找带引号的子字符串的主要内容,如果未能解决你的问题,请参考以下文章

PB中取字符串子串的函数是啥

在所有 oracle 包中查找带引号和双引号的字符串

使用正则表达式在 C# 中使用转义引号查找带引号的字符串

字符串子串的查找

C++编程,查找字符串子串并替换。

数组篇在python中如何查找最长字符串子串