2013-06-12 66 views
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 
) 

回答

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子句並不需要,因爲每行只有一個字符串BUT t一個字符串需要應用於各種變量。

使事情變得複雜的是,需要設置的變量在正在讀取的文件名中用於設置它們。

因此,init標誌初始設置爲非空;一旦第一條數據線被讀取,變量就會被設置。

然後設置下一個尚未設置的目標變量,並清除init標誌以確保每行只讀取一個變量。

+0

這很好,謝謝。快速的問題:如果變量的值在.cfg文件的單獨行中,而不是用逗號分隔,for循環會是什麼樣子? – ariestav

+0

如果變量位於不同的行上,則不需要「令牌」。在這種情況下,您可以連續讀取變量。 – Endoro

+0

不是這樣!再想一想 - 如果項目分開,第一個將應用於%% a並且不會分配其他項目。然後將讀取文件,最後一行是應用於作業的元素。我已經編輯了Endoro的解決方案來回應這個補充問題... – Magoo

0

好吧,我喜歡批處理文件,這一個讓我去了一段時間。你已經告訴過你,你只需要%% a,這就是你所得到的。 Endoro說(當他發佈時我輸入了相同的答案),包括「令牌」關鍵字告訴它它需要哪個令牌。 令牌%% a顯然是第一個,但是通過告訴命令處理器你想要令牌1-9它將它分離並分配給下一個字母「變量」。 而在這種情況下,usebackq是多餘的

+0

usebackq對其功能至關重要。 – ariestav

+0

@AlJones OP通過命令行參數設置第一個for循環的三個參數。你確定沒有空間嗎? – Endoro

+0

關於這個問題的一些事情讓我感到飢餓......關鍵是'usebackq'是必要的,但僅僅是因爲Endoro引入了引用文件名的概念 - 當然這是一個明智的措施。誰能投票反對他們的行動 - 這是一個禮貌的領域,讚賞的貢獻,不像德爾福那樣,有一個相互自我讚賞的社會通常會降低自我任命的統治集團的貢獻。 – Magoo

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(with NO /F選項)。此方法允許在常規for命令中輕鬆分離單個令牌中的值列表,但僅適用於指定的分隔符。