循环的批处理文件无法从外部文件分配值

时间:2013-06-12 03:24:33

标签: batch-file cmd

所以,我有一个名为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
)

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

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 
) 

3 个答案:

答案 0 :(得分:2)

试试这个:

FOR /F "usebackq tokens=1-9 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
)

[补充问题回应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="
)

要从顺序行读取,不需要tokensdelims子句,因为每行只有一个字符串,但需要将一个字符串应用于各种变量。

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

因此,init标志最初设置为非空;读取第一个数据行后设置变量。

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

答案 1 :(得分:0)

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

答案 2 :(得分: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命令中轻松分离单个标记中的值列表,但仅适用于指示的分隔符。