Das Problem mit Ihrem Code ist die Zeile:
SET "line=%%A"
Die Schleifenvariable A
den String-Wert hat:
#define BLE_UUID_!SERVICE_NAME_UC!_!CARACTERISTIC_NAME_UC[%INDEX%]!_CHAR !CARACTERISTIC_UUID[%INDEX%]!
verzögerte Expansion auf die Zuweisung diese Zeichenfolge Umgebungsvariable line
angewendet wird.
Aber sofortige Erweiterung für %INDEX%
ist nicht mehr getan. Windows-Befehlsinterpreter erweitert, um alle Variablenreferenzen Umgebung mit %VariableName%
bereits auf ganzen FüR Befehlsblock Anfang in Ihrem Code mit (FOR /F
Parsen und endend mit ))
bevor Befehl FOR ist das erste Mal überhaupt ausgeführt wird.
Aus diesem Grund wird !SERVICE_NAME_UC!
durch die Zeichenfolge SECURITY
beim Zuweisen der aus der Datei gelesenen Zeile in die Umgebungsvariable line
ersetzt. Der Windows-Befehlsinterpreter kann jedoch keine Umgebungsvariable mit dem Namen CARACTERISTIC_NAME_UC[%INDEX%]
und einer anderen Umgebungsvariablen mit dem Namen CARACTERISTIC_UUID[%INDEX%]
finden. Dies führt dazu, dass sowohl die Pseudo-Array-Referenzen der Umgebungsvariablen durch eine leere Zeichenfolge ersetzt werden.
Ich bin mir nicht sicher, warum Sie die Erstellung der Header-Datei so kompliziert, aber hier ist die Lösung für Ihr Problem, die zusätzliche Zeilen für eine minimal, complete, and verifiable example enthält hinterlässt keine Datei hinter Batch-Dateiausführung abgeschlossen.
@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
Die bereitgestellte Lösung übergibt die Zeile, die von der Datei gelesen wird, an eine weitere Subroutine. Die übergebene Zeile wird zuerst der Umgebungsvariablen Line
im Unterprogramm ExpandLine
zugewiesen.
Next Umgebungsvariablen sofortige Expansion verwenden, werden über die Befehlszeile erweitert:
call set "Line=%Line%"
Nach dieser Befehlszeile die Umgebungsvariable Line
hat bei der ersten Ausführung der Haupt FOR Schleife den String-Wert:
#define BLE_UUID_!SERVICE_NAME_UC!_!CHARACTERISTIC_NAME_UC[1]!_CHAR !CHARACTERISTIC_UUID[1]!
Jetzt ist die verzögerte Erweiterung aktiviert, und diese Zeile wird erneut erweitert, indem zusätzlich eine verzögerte Erweiterung verwendet wird, bevor die zweifach erweiterte Zeile in die Ausgabedatei gedruckt wird.
Ich bin ganz sicher, dass das, was Sie wirklich erreichen wollen viel leichter getan werden könnte, wie unter dem demonstriert auslässt [%INDEX%]
in Datei DefCharUUID.txt
vollständig:
@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
Einige weitere Hinweise:
GOTO ist der Befehl und :EOF
ist der Parameter. Schreiben Sie sie nicht zusammen, obwohl der Windows-Befehlsinterpreter nach dem Anwenden einer Fehlerkorrektur auch GOTO:EOF
behandelt.
Es ist ratsam, andere Skripte oder Anwendungen wie FINDSTR mit vollständigem Pfad und Dateierweiterung in einer Batch-Datei verweist die Batch-Datei unabhängig von aktuellen Werten der lokalen Umgebungsvariablen PATHEXT
und PATH
so viel wie möglich zu machen.
Schließen Sie alle Datei-/Verzeichnisreferenzen in doppelte Anführungszeichen ein, auch wenn sie nicht unbedingt mit den aktuellen Datei-/Verzeichnisnamen/Pfaden benötigt werden, denn wer kennt wirklich die Datei-/Verzeichnisnamen/Pfade in Zukunft.
Warum rufen Sie 'CALL' 'SetOutput_h' mit zwei Argumenten auf, von denen das erste für diese for-Schleife völlig überflüssig ist? Wenn Sie einfach PART_NAME_H =% INPUT_HEADER_PATH% \ DefCharUUID.txt "' vor dieser Schleife setzen, würden Sie nur 'CALL: SetOutput_h %% a' und' SET "INDEX =% 1" 'Ich bemerke aber auch, dass Sie es nicht tun scheinen auch% INDEX% zu benutzen! – Compo