如何使用批处理脚本解析字符串?
目标是将数组中的所有内容保存起来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”变量,但永远不会重置它,或者如果它不再为真,则取消定义它。因此,在第一次设置之后,它将在循环的其余部分保持“已定义”状态。
我倾向于专门设置变量(true
或false
)。将其设置为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