0

所以,我有一个名为 prev_batch.cfg 的基本文本文件,我想要一个批处理脚本来读取它。prev_batch.cfg 是单行文本,但标记用逗号分隔。它看起来像:

apples,oranges,bananas,grapes,strawberries

我希望这些标记中的每一个都进入我在 for 循环中设置的特定变量。问题只是在循环中设置了第一个变量。没有其他的。我希望将所有变量设置为在 .cfg 文件的分隔列表中找到的标记。

这是我的批处理脚本在 FOR 循环结束之前的样子:

@ECHO ON

setlocal EnableDelayedExpansion

SET JOB=%1
SET USER=%2
SET ASSETROOT=%3

:: Read all the arguments for this batch script from external text file
FOR /F "delims=," %%a IN (%ASSETROOT%\users\%USER%\%JOB%\prev_batch.cfg) do (
SET JOB=%%a
SET USER=%%b
SET TEMPLATE=%%c
SET ASSETROOT=%%d
SET SHAREADDR=%%e
SET SHARENAME=%%f
SET SHAREDRIVE=%%g
SET SHAREUSER=%%h
SET SHAREPASS=%%i
)

我正在运行批处理文件并将三个命令行参数传递给它。当批处理运行到日志文件时,我正在输出批处理的回声。这就是我所看到的:

C:\Windows\system32>setlocal EnableDelayedExpansion 

C:\Windows\system32>SET JOB=99D0FAA9-22B8-4FE7-9321-21F5587E8177 

C:\Windows\system32>SET USER=10

C:\Windows\system32>SET ASSETROOT=C:\app 

C:\Windows\system32>FOR /F "delims=," %a IN (C:\app\users\10\99D0FAA9-22B8-4FE7-9321-21F5587E8177\prev_batch.cfg) do (
SET JOB=%a  
 SET USER=%b  
 SET TEMPLATE=%c  
 SET ASSETROOT=%d  
 SET SHAREADDR=%e  
 SET SHARENAME=%f  
 SET SHAREDRIVE=%g  
 SET SHAREUSER=%h  
 SET SHAREPASS=%i 
) 

C:\Windows\system32>(
SET JOB=99D0FAA9-22B8-4FE7-9321-21F5587E8177  
 SET USER=%b 
 SET TEMPLATE=%c  
 SET ASSETROOT=%d  
 SET SHAREADDR=%e  
 SET SHARENAME=%f  
 SET SHAREDRIVE=%g  
 SET SHAREUSER=%h  
 SET SHAREPASS=%i 
) 
4

3 回答 3

2

尝试这个:

FOR /F "usebackq tokens=1-9 delims=," %%a IN ("%ASSETROOT%\users\%USER%\%JOB%\prev_batch.cfg") 做 (
设置工作=%%a
设置用户=%%b
设置模板=%%c
设置资产根=%%d
设置 SHAREADDR=%%e
设置共享名=%%f
设置共享驱动器=%%g
设置共享用户=%%h
SET SHAREPASS=%%i
)

[PW回应补充问题的补充]

SET init=Y
SET "fields=JOB USER TEMPLATE ASSETROOT SHAREADDR SHARENAME SHAREDRIVE SHAREUSER SHAREPASS"

FOR /F "usebackq" %%a IN ("%ASSETROOT%\users\%USER%\%JOB%\prev_batch.cfg") do (
 IF DEFINED init FOR %%i IN (%fields%) DO SET "%%i="
 SET init=Y
 FOR %%i IN (%fields%) DO IF DEFINED init IF NOT DEFINED %%i SET "%%i=%%a"&SET "init="
)

要从连续的行中读取,不需要tokensand子句,因为每行只有一个字符串,但是需要将一个字符串应用于各种变量。delims

使事情复杂化的事实是,需要设置的变量在被读取的文件名中用于设置它们。

因此,init标志最初设置为非空;一旦读取第一条数据线,就会设置变量。

然后设置下一个尚未设置的目标变量并init清除标志以确保每行读取仅设置一个变量。

于 2013-06-12T04:05:58.227 回答
0

还有另一种方法可以通过变量名数组来解决这个问题。这种方法的优点是对变量列表(变量的数量、它们的名称、它们的位置等)的任何修改都是以非常简单的方式进行的,只需修改批处理文件中的一行。

@echo off
setlocal EnableDelayedExpansion

rem Define the list of variable names
set variables=JOB USER TEMPLATE ASSETROOT SHAREADDR SHARENAME SHAREDRIVE SHAREUSER SHAREPASS

rem Convert the list into an array of variable names
set i=0
for %%a in (%variables%) do (
   set /A i+=1
   set variable[!i!]=%%a
)
set numVariables=%i%

:: Read all the arguments for this batch script from external text file

rem Version 1: Single line of text, tokens delimited with comma
set i=0
for /F "delims=" %%a in (%ASSETROOT%\users\%USER%\%JOB%\prev_batch.cfg) do (
   for %%b in (%%a) do (
      set /A i+=1
      for %%i in (!i!) do set !variable[%%i]!=%%b
   )
)

rem Version 2: Values of the variables on separate lines
set i=0
for /F "delims=" %%a in (%ASSETROOT%\users\%USER%\%JOB%\prev_batch.cfg) do (
   set /A i+=1
   for %%i in (!i!) do set !variable[%%i]!=%%a
)

rem Display values of all variables
for %%i in (1,1,%numVariables%) do (
   for %%v in (!variable[%%i]!) do echo %%v = !%%v!
)

在第一个版本中,文件的行以%%a可替换参数读取,然后以for这种方式在命令中处理:

for %%b in (%%a) do (

例如:

for %%b in (apples,oranges,bananas,grapes,strawberries) do (

因为标准批处理分隔符是空格、逗号、分号和等号,所以列表中的值在for(使用 NO/F选项)中被一一处理。for此方法允许在常规命令中轻松分隔单个标记中的值列表,但仅适用于指定的分隔符。

于 2013-06-12T11:20:26.607 回答
0

好吧,我喜欢批处理文件,这个让我走了一段时间。你已经告诉它你只想要 %%a 所以这就是你得到的。正如 Endoro 所说(我在他发布时输入了相同的答案),包括“tokens”关键字告诉它你想要哪些令牌。记号 %%a 显然是第一个,但通过告诉命令处理器您想要记号 1-9,它会将它们分开并将它们分配给下一个按字母顺序排列的“变量”。在这种情况下, usebackq 是多余的

于 2013-06-12T04:18:23.563 回答