2017-03-22 48 views
0

如果我寫如何將參數傳遞到作用於一個外部文件中批量

setlocal EnableDelayedExpansion 
for /L %%a in (1,1,%NUMBER%) do (
    ECHO #define BLE_UUID_!SERVICE_NAME_UC!_!CARACTERISTIC_NAME_UC[%%a]!_CHAR !CARACTERISTIC_UUID[%%a]! 
) 

NUMBERSERVICE_NAME_UCCARACTERISTIC_NAME_UC [%% A]CARACTERISTIC_UUID [%%子程序A]之前已經設置,一切工作正常,我獲得:

#define BLE_UUID_SECURITY_RELAY_CMD_CHAR  0x4800 
#define BLE_UUID_SECURITY_RELAY_STATUS_CHAR  0x4801 
#define BLE_UUID_SECURITY_CONFIG_CHAR 0x4802 

但是,我想喜歡做的事是調用一個子程序裏面的FOR循環,它的任務,如以這樣的方式

setlocal EnableDelayedExpansion 
for /L %%a in (1,1,%NUMBER%) do (
    CALL :SetOutput_h %INPUT_HEADER_PATH%\DefCharUUID.txt %%a 
) 

GOTO:EOF 
:SetOutput_h 
:: Subroutine to insert parts of code in the header output file 
:: The argument for this subroutine is the NAME of the code part you want to insert in the output file 
SET "PART_NAME_H=%~1" 
SET "INDEX=%~2" 
(FOR /F "delims=" %%A IN ('findstr /N "^" %PART_NAME_H%') DO (

    REM Get the line *including* !variable! replacements 
    SET "line=%%A" 

    REM Remove leading number, show the rest *including* empty lines 
    ECHO(!line:*:=! 

)) >> %OUTPUT_H% 
GOTO:EOF 

凡文件DefCharUUID.txt只包含此:

#define BLE_UUID_!SERVICE_NAME_UC!_!CARACTERISTIC_NAME_UC[%INDEX%]!_CHAR !CARACTERISTIC_UUID[%INDEX%]! 

的輸出文件genarated包含此:

#define BLE_UUID_SECURITY__CHAR 

因此,具有方括號的部分已被忽略。

我在做什麼錯?

+0

你爲什麼''調用'':SetOutput_h'有兩個參數,其中第一個是完全多餘的循環?如果你在該循環之前只設置了「PART_NAME_H =%INPUT_HEADER_PATH%\ DefCharUUID.txt」,那麼你只需要'CALL:SetOutput_h %% a'和'SET'INDEX =%1「'雖然我也注意到你沒有似乎也在使用'%INDEX%'! – Compo

回答

0

與您的代碼的問題是該行:

SET "line=%%A" 

循環變量A具有字符串值:

#define BLE_UUID_!SERVICE_NAME_UC!_!CARACTERISTIC_NAME_UC[%INDEX%]!_CHAR !CARACTERISTIC_UUID[%INDEX%]! 

延遲擴展被施加在分配此字符串環境變量line

但是%INDEX%的立即擴展不再被執行。 Windows命令解釋器使用%VariableName%已經在你的代碼(FOR /F解析整個FOR命令塊開始和命令之前))結束在所有第一次執行擴展的所有環境變量的引用。

因此,!SERVICE_NAME_UC!被字符串SECURITY替換爲將文件讀取的行分配給環境變量line。但Windows命令解釋程序無法找到名稱爲CARACTERISTIC_NAME_UC[%INDEX%]的環境變量和名稱爲CARACTERISTIC_UUID[%INDEX%]的另一個環境變量,從而導致兩個環境變量僞數組引用被空字符串替換。

我不知道爲什麼你編碼的頭文件創建如此複雜,但這裏是你的問題的解決方案,其中包含額外的行minimal, complete, and verifiable example批處理文件執行完成後不留下任何文件。

@echo off 
setlocal EnableExtensions 
set "NUMBER=3" 
set "SERVICE_NAME_UC=SECURITY" 
set "CHARACTERISTIC_NAME_UC[1]=RELAY_CMD" 
set "CHARACTERISTIC_NAME_UC[2]=RELAY_STATUS" 
set "CHARACTERISTIC_NAME_UC[3]=CONFIG" 
set "CHARACTERISTIC_UUID[1]=0x4800" 
set "CHARACTERISTIC_UUID[2]=0x4801" 
set "CHARACTERISTIC_UUID[3]=0x4802" 
set "INPUT_HEADER_PATH=%TEMP%" 
set "OUTPUT_H=%TEMP%\output.h" 
del "%OUTPUT_H%" 2>nul 
echo #define BLE_UUID_!SERVICE_NAME_UC!_!CHARACTERISTIC_NAME_UC[%%INDEX%%]!_CHAR !CHARACTERISTIC_UUID[%%INDEX%%]!>"%INPUT_HEADER_PATH%\DefCharUUID.txt" 

for /L %%I in (1,1,%NUMBER%) do (
    call :SetOutput_h "%INPUT_HEADER_PATH%\DefCharUUID.txt" %%I 
) 

type "%OUTPUT_H%" 
del "%OUTPUT_H%" 
del "%INPUT_HEADER_PATH%\DefCharUUID.txt" 
endlocal 
goto :EOF 

:SetOutput_h 
:: Subroutine to insert parts of code in the header output file. 
:: The argument for this subroutine is the NAME of the code part you want to insert in the output file. 
set "INDEX=%~2" 
for /F "delims=" %%L in ('%SystemRoot%\System32\findstr.exe /N "^" "%~1"') do call :ExpandLine "%%L" 
goto :EOF 

:ExpandLine 
set "Line=%~1" 
call set "Line=%Line%" 
setlocal EnableDelayedExpansion 
set "Line=%Line%" 
echo(!Line:*:=!>>"%OUTPUT_H%" 
endlocal 
goto :EOF 

提供的解決方案將從文件讀取的行傳遞給另一個子例程。傳遞的行首先分配給子例程ExpandLine中的環境變量Line

使用立即膨脹接着環境變量使用命令行擴展:

#define BLE_UUID_!SERVICE_NAME_UC!_!CHARACTERISTIC_NAME_UC[1]!_CHAR !CHARACTERISTIC_UUID[1]! 

call set "Line=%Line%" 

此命令行環境變量Line對的主第一運行循環字符串值後

現在啓用延遲擴展,並且在將兩倍擴展行打印到輸出文件之前,使用額外的延遲擴展再次擴展此行。

我敢肯定那是你真正想要實現可以做更容易爲證明其下方的文件DefCharUUID.txt完全省略[%INDEX%]

@echo off 
setlocal EnableExtensions 
set "NUMBER=3" 
set "SERVICE_NAME_UC=SECURITY" 
set "CHARACTERISTIC_NAME_UC[1]=RELAY_CMD" 
set "CHARACTERISTIC_NAME_UC[2]=RELAY_STATUS" 
set "CHARACTERISTIC_NAME_UC[3]=CONFIG" 
set "CHARACTERISTIC_UUID[1]=0x4800" 
set "CHARACTERISTIC_UUID[2]=0x4801" 
set "CHARACTERISTIC_UUID[3]=0x4802" 
set "INPUT_HEADER_PATH=%TEMP%" 
set "OUTPUT_H=%TEMP%\output.h" 
del "%OUTPUT_H%" 2>nul 
echo #define BLE_UUID_!SERVICE_NAME_UC!_!CHARACTERISTIC_NAME_UC!_CHAR !CHARACTERISTIC_UUID!>"%INPUT_HEADER_PATH%\DefCharUUID.txt" 

setlocal EnableDelayedExpansion 
for /L %%I in (1,1,%NUMBER%) do (
    set "CHARACTERISTIC_NAME_UC=!CHARACTERISTIC_NAME_UC[%%I]!" 
    set "CHARACTERISTIC_UUID=!CHARACTERISTIC_UUID[%%I]!" 
    for /F "delims=" %%L in ('%SystemRoot%\System32\findstr.exe /N "^" "%INPUT_HEADER_PATH%\DefCharUUID.txt"') do (
     set "Line=%%L" 
     echo(!Line:*:=!>>"%OUTPUT_H%" 
    ) 
) 
endlocal 

type "%OUTPUT_H%" 
del "%OUTPUT_H%" 
del "%INPUT_HEADER_PATH%\DefCharUUID.txt" 
endlocal 

一些更多的提示:

GOTO是命令並且:EOF是參數。儘管Windows命令解釋器在應用糾錯之後還處理GOTO:EOF,但不要將它們編寫在一起。

明智的做法是引用其他腳本或應用程序,如FINDSTR完整路徑和文件擴展名的批處理文件,以使獨立對當地環境變量PATHEXTPATH儘可能的電流值的批處理文件。

將所有文件/目錄引用放在雙引號中,即使對於當前文件/目錄名稱/路徑不是真的需要,因爲誰將來真正知道文件/目錄名稱/路徑。

相關問題