使用批处理脚本解析字符串

使用批处理脚本解析字符串

如何使用批处理脚本解析字符串?

目标是将数组中的所有内容保存起来Import:,然后删除,#head例如 -->//MPackages/Project/config/abc.txt//Packages/Project/config/cde.txt

测试.txt:

Version: 4.5.0
Import:
   //MPackages/Project/config/abc.txt                       #head
   //Packages/Project/config/cde.txt                        #head
View:
  //MPackages/Project/config/ac.txt                     #head
  //Packages/Project/config/de.txt                      #head

我的尝试:

@echo off

set buildlog="devel.p4inc"

setlocal EnableDelayedExpansion
for /F "tokens=*" %%A in  (devel.p4inc) do  (
  if /i "%%A"=="Import:" set "import=true"
  IF DEFINED import (echo %%A)
)

期望输出

   //MPackages/Project/config/abc.txt 
   //Packages/Project/config/cde.txt

导入下的任何内容:

答案1

您的逻辑中的主要问题之一是,如果某项为真,您会设置一次“import”变量,但永远不会重置它,或者如果它不再为真,则取消定义它。因此,在第一次设置之后,它将在循环的其余部分保持“已定义”状态。

我倾向于专门设置变量(truefalse)。将其设置为false开始,然后true根据需要将其设置为 ,但还要确保false在需要时将其重新设置为 。然后,在循环的每次迭代中检查变量是否专门设置为True或 ,False而不是检查它是否只是定义。

根据您的信息/目标,此代码对我有用:

@echo off

setlocal EnableDelayedExpansion

set buildlog=test.txt
set import=false

for /F "tokens=*" %%A in (%buildlog%) do (
    if /i "%%A"=="Import:" (
        set import=true
    )
    if /i "%%A"=="View:" (
        set import=false
    )
    if !import!==true (
        if not "%%A"=="Import:" (
            for /F "tokens=1" %%B in ("%%A") do (
                echo %%B
            )
        )
    )
)

我们特意将“导入”变量(标志)设置为false开始。

第一个 For 循环遍历文件中的每一行(test.txt在此示例中,由“buildlog”变量指定;注意:您需要删除变量中文件名周围的引号才能在 For 循环中工作)。

第一个 IF 查看当前行是否是“Import:”行,如果是,则将“import”标志翻转为true

下一个 IF 查看当前行是否为“View:”行,如果是,则将“import”标志翻转(返回)为false,以便停止处理每一行。

第三个 IF 检查“导入”标志是否为true,如果是,则处理该行。

如果是true,则嵌套的(第 4 个)IF 检查该行是否是实际的“import:”行,如果不是,则显示该行(防止在输出中显示“Import:”行)。

第二个 For 循环遍历我们想要显示的行,并且仅拉出第一个 Token 集,该集(仅)是您想要的路径,而忽略#head

更多/相关信息:

评论后编辑:

要处理“View:”行后面是否有版本号,您可以将代码修改为类似以下内容:

@echo off

setlocal EnableDelayedExpansion

set buildlog=test.txt
set import=false

for /F "tokens=*" %%A in (%buildlog%) do (
    for /F "tokens=1" %%B in ("%%A") do (
        if /i "%%B"=="Import:" (
            set import=true
        )
        if /i "%%B"=="View:" (
            set import=false
        )
        if !import!==true (
            if not "%%B"=="Import:" (
                for /F "tokens=1" %%C in ("%%A") do (
                    echo %%C
                )
            )
        )
    )
)

添加的 For 循环会从行中取出第一个标记来检查它是“View:”还是“Import:”,而不是检查整行。实际上,在检查时会忽略行中遇到的第一个空格之后的任何内容。

答案2

@echo off
for /F "usebackq tokens=1" %%A in  ("devel.p4inc") do  (
Set temp=False
if "%%A" == "View:" Goto Exit
if  not "%%A" == "Import:" if  not "%%A" == "Version:"  echo %%A
)
:Exit

答案3

命令行:

powershell [string]$f=gc test.txt;$pL=$f.IndexOf('Import:')+7;$pR=$f.IndexOf('View:');$s=$f.Substring($pL,$pR-$pL);$s -split'#head'^|ac result.txt

电源外壳:

powershell ./parsefl.ps1

解析fl.ps1

[string]$f=gc test.txt;
$pL=$f.IndexOf('Import:')+'Import:'.Length;$pR=$f.IndexOf('View:');
$s=$f.Substring($pL,$pR-$pL);
$s -split'#head'|ac result.txt

相关内容