Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 循环的批处理文件无法从外部文件分配值_Batch File_Cmd - Fatal编程技术网

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

Batch file 循环的批处理文件无法从外部文件分配值,batch-file,cmd,Batch File,Cmd,所以,我有一个名为prev_batch.cfg的基本文本文件,我想要一个批处理脚本来读取它。prev_batch.cfg是单行文本,但标记用逗号分隔。它看起来像: apples,oranges,bananas,grapes,strawberries 我希望这些标记中的每一个都进入我在for循环中设置的特定变量。问题是在循环中只设置了第一个变量。没有别的了。我希望所有变量都设置为.cfg文件中分隔列表中的标记 下面是我的批处理脚本在FOR循环结束之前的样子: @ECHO ON setlocal

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

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 ) 要从顺序行读取,不需要
标记
delims
子句,因为每行上只有一个字符串,但需要将该字符串应用于各种变量

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

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


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

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

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

@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
中逐个处理(不带
/F
选项)。此方法允许在常规的
for
命令中轻松分离单个标记中的值列表,但仅适用于指定的分隔符。

usebackq对其功能至关重要。@AlJones OP通过命令行参数设置其第一个for循环的三个参数。你确定里面没有空间吗?这个问题让我饿了。。。关键是,
usebackq
是必要的,但这仅仅是因为endro引入了引用文件名的概念——这当然是一个明智的措施。不管是谁投票否决了这一回应,请扭转他们的行动——这是一个尊重贡献的礼貌领域,而不像说德尔菲,在德尔菲,一个相互自我欣赏的社会经常否决自封统治集团的贡献。@endro-:)好吧,我站在正确的立场,给出了合乎逻辑的理由。不是我投了反对票,除非信息完全不正确,否则我不会。很好,讨论内容丰富。这非常有效,谢谢。快速问题:如果变量的值在.cfg文件的单独行上而不是用逗号分隔,for循环会是什么样子?如果变量在单独行上,则不需要
标记。在这种情况下,您可以连续读取变量。情况并非如此!再想一想-如果项目在单独的行中,则第一个将应用于%%a,而不分配其他项目。然后读取文件,最后一行是应用于作业的元素。我编辑了Endro的解决方案来回答这个补充问题…@Peter问题是
如果变量的值在单独的行上,for循环会是什么样子
,我关于for循环的回答是正确的:),不过谢谢你的评论。。。。
for %%b in (apples,oranges,bananas,grapes,strawberries) do (