warum wird beim ersetzen von Wörtern in einer TXT Datei mit einer Batch Datei die Ausrufezeichen gelöscht?

2 Antworten

Wenn die Möglichkeit besteht, das eine Eingabe oder Ausgabe Ausrufezeichen enthält sollte man auf verzögerte VariableExpansion verzichten.

Wenn das Statement SETLOCAL EnableDelayedExpansion gesetzt wurde, wird das Ausrufezeichen! zu Variablenmarker.

Output.cmd

echo hallo du (3 Ausrufezeichen:!!! ...geht
setlocal enableDelayedExpansion
  rem Falsch
echo hallo du (3 Ausrufezeichen:!!! ...geht nicht mehr 
  rem richtig 
echo hallo du (3 Ausrufezeichen:^^!^^!^^! ...geht
pause

input falsch.cmd

set "myVar=Hallo Du!!!"
echo hier  ist  noch alles  ok: "%myVar%"

setlocal enableDelayedExpansion
echo ja unsere Variable  enthält nachwievor die Ausrufezeichen
set myvar
   rem  ...funktioniert, als  würdest Du die Zeiel aus eienr Datei lesen
for /f "tokens=*" %%a in ("%myVar%") do (
      rem mist,  die Ausrufezeichen  wurden gefressen 
    set "myNewVar=%%a"
    set "myNewVar"
     echo %%a  
) 
pause

...wir wollen aber unbedingt innerhalb der Schleife nur das "Du" gegen "Ihr" tauschen ohne die Ausrufezeichen zu verlieren.

set "myVar=Hallo Du!!!"
for /f "tokens=*" %%a in ("%myVar%") do (
    echo alles noch da: %%a 
    set "myNewVar=%%a"
      rem  zugriff auf Variablen Innerhaln  von Klammerblöcken
    call set "myNewVar=%%myNewVar:Du=Ihr%%"
    call echo %%myNewVar%%
) 
pause

call set/echo %%var%% ist schrecklich lahm (relativ gesehen). ...und funktioniert nicht mit if.

Wenn viele Variablenzuweisungen und Vergleiche innerhalb eines Klammerblocks nötig sind, sollte man das gesamte Prozetere in eine Subroutine auslagern und nur diese innerhalb des Schleifenrumpfes aufrufen (Argumente können Übergeben werden.

set "myVar=Hallo Du!!!"
for /f "tokens=*" %%a in ("%myVar%") do (
  call :mySub "%%a"
) 
pause
exit /b

 rem die Angabe Parms... dient nur der Erinnerung für den Programmierer was welches Argument enthält
:mySub  params: %1="ein String"
 rem hier kannst Du ganz normal auf Variablen zugreifen 
 rem Du befindest Dich nicht nur In eienr Subroutine , sondern auch in einer neuen Instanz von Cmd mit einem eigenen Subset an Variablen
 rem ...als wärst Du in einer anderen Batch
echo alles noch da: %~1 
set "myNewVar=%~1"
set "myNewVar=%myNewVar:Du=Ihr%"
if "%myNewVar%"=="Hallo Ihr!!!" (echo hat geklappt)
echo %myNewVar%
exit /b

Batch war noch nie einfach und ist nicht wirklich zur automatisierten Texverarbeitung geeignet. (Was Glaubst Du was passeirt wen Deine Dateien Sachen wie: (&|<>"?*) enthalten (zumal Du nicht eine Set-Zuweisung in "Gänsefüßchen" geführt hast). Auch Klammern, Quotes, stern und Fragezeichen können tückisch sein!

Batch ist eine Sprache zur administrativen Verwaltung des Systems.

Die Möglichkeiten der Textverarbeitung beschränken sich auf die Verarbeitung von vorhersehbaren Ausgaben von Programmen oder Logfiles etc, bei denen man vorher weiß was drin stehen kann und was nicht.

Woher ich das weiß:eigene Erfahrung – Ich mach das seit 30 Jahren

Das Rufzeichen hat in Batch-Dateien eine Sonderfunktion, daher musst du vorher den sogenannten Escape-Character setzen, damit diese Sonderfunktion nicht zum Tragen kommt.

Normalerweise ist das Escape-Zeichen bei Batch "^", beim Rufzeichen muss man allerdings zwei davon setzen, damit es korrekt funktioniert, außer man setzt den String unter Anführungszeichen, dann reicht einmal.

Du musst also

^^!

eingeben statt nur "!".

Hier ein hilfreicher Stackoverflow-Beitrag hierzu:

https://stackoverflow.com/questions/3288552/how-can-i-escape-an-exclamation-mark-in-cmd-scripts

Woher ich das weiß:Berufserfahrung – arbeite seit vielen Jahren in der IT
SonOfEpic 
Fragesteller
 19.02.2021, 10:01

also überall wo in der Batch Datei ein Ausrufezeichen steht müssen zwei Escape Zeichen stehen ?

0
TheFamousSpy  19.02.2021, 10:09
@SonOfEpic

Nein, sondern nur dort wo es "sinn" macht.

SET ganze_zeile=!ganze_zeile:C074AD0B0BFA=%MacAdresse%!

ECHO !ganze_zeile!

ECHO !ganze_zeile! >> %ziel%

Bei den Echo-Befehlen sind die Rufzeichen richtig, weil du ja hier eine Variable in einer For-Schleife ausgeben willst. Wenn du hier die Escape Characters setzt wäre die Ausgabe nicht die Variable "ganze_zeile" mit der Mac-Adresse sondern du würdest den Text "!ganze_zeile!" ausgeben. Das macht hier keinen Sinn.

In der ersten Zeile (beginnt mit SET) willst du ja scheinbar, dass die Zeile mit einem Rufzeichen beginnt und mit einem Rufzeichen endet. Hier würdest du die Escape Character eben brauchen.

1
SonOfEpic 
Fragesteller
 19.02.2021, 10:21
@TheFamousSpy

in der Batch hat es leider nicht funktioniert aber in der text Datei :)

ich hab ein Escape zeichen vor und nach dem Ausrufezeichen gesetzt und das funktioniert super

1