Batch file 循环的批处理文件无法从外部文件分配值
所以,我有一个名为prev_batch.cfg的基本文本文件,我想要一个批处理脚本来读取它。prev_batch.cfg是单行文本,但标记用逗号分隔。它看起来像: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
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 (