如何批量从文本文件中获取多个案例?

How to get multiple cases from text file with batch?

我有一个配置文本文件 包含案例,我必须为每个案例调用另一个批处理脚本。我的配置 txt 看起来像这样,我有多个案例具有相同的可选属性:

main:
  - case1:
     a: 123
     b: 321
     c: 654
  - case2: 
     b: 523
     d: 736
     a: 834
  - case3: 
     c: 231
     d: 246

我必须调用另一个脚本并将属性作为参数,(case3):

call script2.bat null null 231 246

我尝试使用 for 循环遍历文本文件,但我不知道如何区分大小写并使用正确的值调用第二个脚本。如果可能的话,我想只使用批处理。

setlocal enabledelayedexpansion
for /f "tokens=*" %%a in (test.txt) do (
   set line=%%a
   if "!line:~0,1!"=="a" (
      set a=!line:a: =!
   )
)

提前致谢

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory & filenames are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q71733362.txt"

SET "parmlist=a b c d"

FOR /f "usebackqtokens=1,2delims=:- " %%b IN ("%filename1%") DO (
 IF /i "%%b"=="main" FOR %%b IN (%parmlist% invalidlist) DO SET "%%b=null"
 FOR %%e IN (%parmlist%) DO IF /i "%%e"=="%%b" SET "%%e=%%c"&SET "invalidlist="
 SET "case=%%b"
 IF /i "!case:~0,4!"=="case" IF NOT DEFINED invalidlist (
  SET "params="
  FOR %%e IN (%parmlist%) DO SET "params=!params! !%%e!"&SET "%%e=null"
  ECHO CALL script2!params!
  SET "invalidlist=Y"
 )
)

IF NOT DEFINED invalidlist (
 SET "params="
 FOR %%e IN (%parmlist%) DO SET "params=!params! !%%e!"
 ECHO CALL script2!params!
)

GOTO :EOF

usebackq 选项是必需的,因为我选择在源文件名周围添加引号。

使用 set "var1=data" 设置字符串值 - 这避免了尾随空格引起的问题。

我一直使用 if /i 来制作 string-match case-insensitive。如果您想要 case-sensitive 匹配,请省略 /i

parmlist 设置为您希望传递给 script2 的参数列表。

使用:-Space作为分隔符读取文件,将找到的第一个标记分配给%%b和第二个 %%c(请参阅提示中的 for /? 或搜索大量 SO 响应以获取文档)

如果第一个标记是 main,则将 parmlist 中的所有变量和标志 invalidlist 设置为值 null

尝试将第一个标记与 parmlist 中的值匹配。在一场比赛中,将找到的参数值设置为第二个标记并将 invalidlist 设置为 nothing 取消定义 invalidlist.

设置case为第一个参数的值,并检查前4个字符。如果这些匹配 caseinvalidlist 未定义(因此已定义参数),则通过添加 Space 值构建 params为列表中的每个参数找到(或 null 如果没有找到该案例的值)。并将参数值设置回 null.

我已经 echo编辑了 script2 调用以进行验证。删除 echo 关键字以实际执行 script2.

参数值现已全部重置为 null,因此将 invalidlist 设置为一个值,因为列表现在无效。

最后,如果未设置 invalidlist,我们已经构建了最后一个案例,因此为最后一个案例生成 call

注意:我假设参数的值永远不会为负,因为否则缺乏信息。


回应评论 - 'case' 可能是其他字符串

SET "invalidlist=Y"
FOR /f "usebackqtokens=1,2delims=:- " %%b IN ("%filename1%") DO (
 IF "%%c" equ "" (
  IF /i "%%b"=="main" (
   FOR %%b IN (%parmlist% invalidlist) DO SET "%%b=null"
  ) ELSE (
   IF NOT DEFINED invalidlist (
    SET "params="
    FOR %%e IN (%parmlist%) DO SET "params=!params! !%%e!"&SET "%%e=null"
    ECHO CALL script2!params!
    SET "invalidlist=Y"
   )
  )
 ) ELSE FOR %%e IN (%parmlist%) DO IF /i "%%e"=="%%b" SET "%%e=%%c"&SET "invalidlist="

)

IF NOT DEFINED invalidlist (
 SET "params="
 FOR %%e IN (%parmlist%) DO SET "params=!params! !%%e!"
 ECHO CALL script2!params!
)

上面的程序代替原来的for循环和clean-up应该允许使用任何单个单词(main除外)代替case

包含单个单词且具有任意数量的前导或尾随定界符的行将导致 %%b 包含该单词而 %%c 为空字符串,因此测试该条件并测试 %%b for main - 初始化变量或 something-else - 输出任何累积数据。

如果%%c包含一些东西,那么尝试像以前一样将它放入适当的变量中。

这是我对此的看法:

@echo off
set cnt=0 & set casen=0
setlocal enabledelayedexpansion
for /f "tokens=1-3*delims=: " %%i in ('type test.txt ^| findstr /V "main:"') do (
    set "line=%%i %%j"
    set /a cnt+=1
    if "%%i" == "-" (
       set "case=!casen!"
       set /a casen+=1
       set cnt=
       for %%f in (a b c d) do set "_%%f=null"
  )
  for %%f in (a b c d) do if "%%f" == "%%i" set "_%%f=%%j"
  set "case!casen!=!_a! !_b! !_c! !_d!"
)
for %%e in (1,1,%casen%) do echo call script2.bat !case%%e!

还可以进一步缩短,但我已经花了一点时间,你已经有了一个可以接受的答案。如果您愿意,请随时改进它。