schnulle500
Goto Top

Batch-Templatefile ausfüllen mit Batch-Script

Ich habe ein Template-Batchscript, in welchem ich mittels einem zweiten Batchscript bestimmte mit $Bezeichner$ markierte Stellen ersetzen möchte. Im Template-Batchscript ist die Delayed-Expansion aktiviert. D.h. es sind somit sowohl variablen im Format %var_x% als auch
im Format !var_y! verwendet.
Nachstehendes Script funktioniert schon soweit, daß die Bezeicher ersetzt und Leerzeilen, Leerzeichen und mit Doppelpunkt beginnende Zeilen übernommen werden.
Problem:
(1) %%a Variablen werden zu %a
(2) %var_x% Variablen gehen komplett verloren
(3) !var_y! Variablen gehen komplett verloren
(4) %CD% aus Template wird mit echo in File schon aufgelöst.

Kann mir bitte jemand weiterhelfen?

Ich hab's auch schon mit DISABLEDELAYEDEXPANSION versucht. Sah bzgl. der !var_y! Variablen besser
aus. Jedoch kriegt ich dann die Syntax mit dem Ersetzen der Template-Bezeicher in den set - Statements innerhalb
Subroutine ReplaceText nicht mehr auf die Reihe, da der neue Text aus einer Variable kommt und kein Literal ist.

:: ****************************************************************************
:: This batch script copies the template of the build script
:: to the specified project directory and customizes the copy by applying the
:: remaining input parameters of this batch script.
:: ****************************************************************************
ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

:: Pares the command line arguments
:: %1..%x -> Command line arguments
:: PROJ_DIR<- Path of project directory (unquotet)
:: TOOL_PATH  - Path of Tool installation directory (unquotet)
:: COMPILER_PATH - Path of GCC compiler directory (unquotet)
:: OUTPUT_FILENAME - File name of resulting module
:: GCC_USERDEFINES - Set of userdefined compiler defines: [-Ddefine_n [-Ddefine_n+1]]
SET PROJ_DIR=%~1
SHIFT
SET TOOL_PATH=%~1
SHIFT
SET COMPILER_PATH=%~1
SHIFT
SET OUTPUT_FILENAME=%~1
SET GCC_USERDEFINES=
:NEXT_CMDLINE_ARG
SHIFT
IF NOT [%1]== (
  SET GCC_USERDEFINES=!GCC_USERDEFINES! -D%1
  GOTO NEXT_CMDLINE_ARG
)
:: Remove the leading space character
SET GCC_USERDEFINES=%GCC_USERDEFINES:~1%

ECHO PROJ_DIR : %PROJ_DIR%
ECHO TOOL_PATH : %TOOL_PATH%
ECHO COMPILER_PATH : %COMPILER_PATH%
ECHO OUTPUT_FILENAME : %OUTPUT_FILENAME%
ECHO GCC_USERDEFINES : %GCC_USERDEFINES%

IF EXIST "%PROJ_DIR%\build.bat" (  
  ECHO Deleting existing build script file
  DEL "%PROJ_DIR%\build.bat"  
  IF ERRORLEVEL 1 GOTO EXIT_WITH_ERROR 
)

ECHO Customizing build script
for /F "delims=] tokens=1,*" %%a in ('find /n /v "" build.bat.template') do call :ReplaceText "%%b" "%PROJ_DIR%\build.bat"   

GOTO :EOF

:ReplaceText
  set "TEXT=%~1"   
  if "!TEXT!"=="" (echo.>>%2) && goto :eof   
  set TEXT=!TEXT:$TOOL_PATH$=%TOOL_PATH%! 
  set TEXT=!TEXT:$COMPILER_PATH$=%COMPILER_PATH%! 
  set TEXT=!TEXT:$OUTPUT_FILENAME$=%OUTPUT_FILENAME%! 
  set TEXT=!TEXT:$GCC_USERDEFINES$=%GCC_USERDEFINES%! 
  >>%2 echo !TEXT!
GOTO :EOF

:EXIT_WITH_ERROR
ECHO COPYING OR CUSTOMIZING BUILD SCRIPT FAILED.
EXIT /b 1
Kommentar vom Moderator Biber am May 24, 2009 um 20:57:47 Uhr
Frage verschoben von "Windows" nach "Batch & Shell".

Content-Key: 116670

Url: https://administrator.de/contentid/116670

Printed on: April 19, 2024 at 19:04 o'clock

Member: bastla
bastla May 24, 2009 at 20:38:32 (UTC)
Goto Top
Hallo Schnulle500 und willkommen im Forum!

Zum Thema ":ReplaceText": Mit der folgenden Alternativ-Variante solltest Du auch ohne "delayedExpansion" auskommen können:
:ReplaceText
  set "TEXT=%~1"    
  if "%TEXT%"=="" (echo.>>%2) && goto :eof    
  call set "TEXT=%%TEXT:$TOOL_PATH$=%TOOL_PATH%%%"  
  call set "TEXT=%%TEXT:$COMPILER_PATH$=%COMPILER_PATH%%%"  
  call set "TEXT=%%TEXT:$OUTPUT_FILENAME$=%OUTPUT_FILENAME%%%"  
  call set "TEXT=%%TEXT:$GCC_USERDEFINES$=%GCC_USERDEFINES%%%"  
  >>%2 echo %TEXT%
GOTO :EOF
Was "%%a" wird zu "%a" bzw "%cd% wird ausgelöst" anlangt: Jedes verdoppelte %-Zeichen wird im Batch zu einem einfachen reduziert, daher eben zB "%%%%a" oder "%%cd%%" verwenden ...
Grüße
bastla

P.S.: Zu mehr reicht's bei mir heute leider nicht ...
Mitglied: 77559
77559 May 24, 2009 at 20:40:39 (UTC)
Goto Top
Hallo Schnulle500,

warum überhaupt die $ Zeichen? Wenn du im Template die $ durch % ersetzt und alle % die den Transport "überleben" sollen verdoppelst (und doppelte vervierfachst) sollte das eigentlich gehen ohne explizierte Ersetzungen.

Gruß
LotPings
Member: Schnulle500
Schnulle500 May 25, 2009 at 07:24:44 (UTC)
Goto Top
Hallo,
vielen Dank für die sehr schnell Hilfe. Das hat mich dem Ziel schon sehr viel näher gebracht.
Ist es denn auch möglich, die % durch eine Stringsubstitution automatisch vorab durch %% zu ersetzen? Folgende Anweisung bringt nicht den erwarteten Effekt:
call set "TEXT=%%TEXT:^%=^%^%%%"  
Gruß
Schnulle500
Member: Biber
Biber May 25, 2009 at 07:46:52 (UTC)
Goto Top
Moin Schnulle500,

ich bin mir relativ sicher, dass wir Deinen Batch auch mit gesetzter "DelayedExpansion" zu Fliegen bringen könnten.

Damit geht es problemlos:
Demo am CMD-Prompt:

(= 9:45:39  D:\temp=)
>set "testzeile=hier soll so was wie %var% stehen"  
>set testzeile & @echo !testzeile:%=%%!
testzeile=hier soll so was wie %var% stehen
hier soll so was wie %%var%% stehen

Grüße
Biber
Member: Schnulle500
Schnulle500 May 25, 2009 at 08:40:52 (UTC)
Goto Top
Boa, das geht aber schnell hier mit den Antworten.

Ich mußte die DelayedExtensions disabeln, da sonst auch noch die !var! im Batch-Template Probleme machen.

Wie sieht den die Syntax ohne die DelayedExtensions aus?
Folgendes funktioniert nämlich nicht:
set testzeile & @echo %testzeile:%=%%%
Mitglied: 77559
77559 May 25, 2009 at 08:49:30 (UTC)
Goto Top
Zitat von @Biber:
ich bin mir relativ sicher, dass wir Deinen Batch auch mit gesetzter "DelayedExpansion" zu Fliegen bringen könnten.
Damit geht es problemlos: Demo am CMD-Prompt:

Moin Biber.

Das Problem in seinem Bach ist aber das er die eingelesene Zeile per Argument dem Call mitgibt.
Dadurch wird das % aber schon ausgewertet und erscheint in der sub gar nicht erst.

Ausweg ist, es in der for Schleife einer Variable zuzuweisen und diese in der Sub zu referenzieren.

@Schnulle500
Versuche es mal mit dieser geänderten Version Zeilen ab 45 austauschen:
ECHO Customizing build script
for /F "delims=] tokens=1,*" %%a in (  
 'find /n /v "" build.bat.template'  
   ) do set "TEXT=%%b" & call :ReplaceText "%PROJ_DIR%\build.bat"   

GOTO :EOF

:ReplaceText
if "!TEXT!"=="" (echo.>>%1) && goto :eof  
set "TEXT=%TEXT:"=¬%"  
set "TEXT=%TEXT:^=^^%"  
set "TEXT=%TEXT:&=^&%"  
set "TEXT=%TEXT:<=^<%"  
set "TEXT=%TEXT:>=^>%"  
set "TEXT=%TEXT:(=^(%"  
set "TEXT=%TEXT:)=^)%"  
set "TEXT=%TEXT:|=^|%"  
set "TEXT=%TEXT:¬="%"  

set TEXT=!TEXT:$TOOL_PATH$=%TOOL_PATH%! 
set TEXT=!TEXT:$COMPILER_PATH$=%COMPILER_PATH%! 
set TEXT=!TEXT:$OUTPUT_FILENAME$=%OUTPUT_FILENAME%! 
set TEXT=!TEXT:$GCC_USERDEFINES$=%GCC_USERDEFINES%! 
>>%1 echo !TEXT!
GOTO :EOF

:EXIT_WITH_ERROR
ECHO COPYING OR CUSTOMIZING BUILD SCRIPT FAILED.
EXIT /b 1
Member: Schnulle500
Schnulle500 May 26, 2009 at 09:18:14 (UTC)
Goto Top
Also was jetzt prima funktioniert ist:
::do.bat "C:\proj" "C:\tool" "C:\compiler" out.o myoem 

ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION

SET PROJ_DIR=%~1
SHIFT
SET TOOL_PATH=%~1
SHIFT
SET COMPILER_PATH=%~1
SHIFT
SET OUTPUT_FILENAME=%~1
SHIFT
SET TARGET_OEM=%~1

ECHO PROJ_DIR : %PROJ_DIR%
ECHO TOOL : %TOOL_PATH%
ECHO COMPILER_PATH : %COMPILER_PATH%
ECHO OUTPUT_FILENAME : %OUTPUT_FILENAME%
ECHO TARGET_OEM : %TARGET_OEM%

IF EXIST "%PROJ_DIR%\build.bat" (  
  ECHO Deleting existing build script file
  DEL "%PROJ_DIR%\build.bat"  
  IF ERRORLEVEL 1 GOTO EXIT_WITH_ERROR 
)

ECHO Customizing build script
FOR /F "delims=] tokens=1,*" %%a IN ('FIND /N /V "" build.bat.template') DO (  
  SET TEXT=%%b
  CALL :REPLACETEXT "%PROJ_DIR%\build.bat"  
)  

GOTO :EOF

:REPLACETEXT
  if "%TEXT%"=="" (echo.>>%1) && goto :eof    
  call set "TEXT=%%TEXT:$TOOL_PATH$=%TOOL_PATH%%%"  
  call set "TEXT=%%TEXT:$COMPILER_PATH$=%COMPILER_PATH%%%"  
  call set "TEXT=%%TEXT:$OUTPUT_FILENAME$=%OUTPUT_FILENAME%%%"  
  call set "TEXT=%%TEXT:$TARGET_OEM$=%TARGET_OEM%%%"  
  >>%1 ECHO.%TEXT%
GOTO :EOF


:EXIT_WITH_ERROR
ECHO COPYING OR CUSTOMIZING BUILD SCRIPT FAILED.
EXIT /b 1

Mit zwei Einschränkungen, die ich nicht begreife:
(1) Folgende Anweisung im Template-Script läßt die Scriptausführung mit Fehler abbrechen:
SET REG_KEY="HKEY_LOCAL_MACHINE^\SOFTWARE^\Cygnus Solutions^\Cygwin^\mounts v2^\/"  

(1) FOR /F Schleife im Template-Script läßt die Scriptausführung mit Fehler abbrechen. Die Parameter werden angemäkelt ("token=...")
FOR /F "tokens=3*" %%v in (file.txt) do ..  
Mitglied: 77559
77559 May 26, 2009 at 11:13:43 (UTC)
Goto Top
Zitat von @Schnulle500:
Mit zwei Einschränkungen, die ich nicht begreife:
(1) Folgende Anweisung im Template-Script läßt die Scriptausführung mit Fehler abbrechen:
> SET REG_KEY="HKEY_LOCAL_MACHINE^\SOFTWARE^\Cygnus  
> Solutions^\Cygwin^\mounts v2^\/"  
> 

Was glaubst du wofür in meiner geposteten Ergänzung die ganzen
Set Test=%Test:<=^>%
Zeilen sind?

Im übrigen ist das in dem Template sowieso Lötzinn, das Backslash ist für die Reg.exe Zeile ein Escape für z. Bsp. das Anführungszeichen, Die einzelnen \ im Pfad brauchen NICHT mit dem Batch Escape versehen werden.

(1) FOR /F Schleife im Template-Script läßt die
Scriptausführung mit Fehler abbrechen. Die Parameter werden
angemäkelt ("token=...")
> FOR /F "tokens=3*" %%v in (file.txt) do ..  
> 

Nimm einfach meine vorgeschlagene Änderung ab Zeile 45 statt deiner Originalzeilen.


Gruß
LotPings
Member: Schnulle500
Schnulle500 May 28, 2009 at 10:32:54 (UTC)
Goto Top
Sorry, dass ich hier nochmal nachfrage. Aber das Problem tritt schon im Vergliech auf.
if "%TEXT%"==""

Ich hab das mal zusammengefaßt:

Das eingedampfte Batch, welches nachstehende "Template" einließt und auf der Console wieder ausgibt:
ECHO OFF
SETLOCAL DISABLEDELAYEDEXPANSION
CLS

FOR /F "delims=] tokens=1,*" %%a IN ('FIND /N /V "" template.bat') DO (  
  SET TEXT=%%b
  CALL :REPLACETEXT
)  

GOTO :EOF

:REPLACETEXT
  if "%TEXT%"=="" (echo.) && goto :EOF  
  call set "TEXT=%%TEXT:$replace$=ersetzt%%"    
  echo.%TEXT%
GOTO :EOF

Das Template sieht zu Testzwecken folgendermaßen aus und ist für sich auch tadellos so ausführtbar,.d.h. es wird der gewünschte Registry-Wert angezeigt. Ich bekomm nur die eine Zeile nicht durch das obige Ersetzungsscript durch.
::zeile 1 ()

SET TEST=!abcd!
SET TEST2=$replace$

SET REG_KEY="HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/"  
REG QUERY %REG_KEY% /v "native"  

::zeile 8

Ausgabe:
::zeile 1 ()

SET TEST=!abcd!
SET TEST2=ersetzt

"Solutions\Cygwin\mounts" ist syntaktisch an dieser Stelle nicht verarbeitbar.  

Kannst Du mir bitte nochmals einen Tipp geben?