Fehler "test!" kann syntaktisch an dieser Stelle nicht verarbeitet werden, beheben?
@echo off
setlocal enableextensions disabledelayedexpansion
set "search=)" set "replace=test"
set "textFile=test.txt"
for /f "delims=" %%i in ('type "%textFile%" ^& break ^> "%textFile%" ') do (
set "line=%%i"
setlocal enabledelayedexpansion
>>"%textFile%" echo(!line:%search%=%replace%!
endlocal
)
2 Antworten
ja...die klammer war's ...und nicht die Nachtigal... Shakespeare?
Bei Batch liegt ein Fehler gerne bei Sonderzeichen und deren Verwendung.
Die nackte Klammer hat deine Batch vergiftet🤢👻
enableDelayedExpansion ist ja nett, nur darf der Text keine Ausrufezeichen enthalten.
Es gibt noch mehr Gift , das ich hier erstmal nicht behandle.
=*~ lassen sich nicht mit Set austauschen!
Das würde jedoch an dieser Stelle zu explodierenden Köpfen führen 😵😱🥵
den Rest habe ich im Code kommentiert
@echo off
rem Klammern und gewisse Sonderzeichen in Texten und Variablen können unter Batch extrem giftig sein
rem außerhalb eines Blocks geht das:
echo ()
rem aber nicht innerhalb eines Klammerblocks
rem sonderzeichen müssen Maskeiert werden_
set "search=^)"
set "replace=:^(test"
set "textFile=test.txt"
rem der Buffertrick ist soweit Ok, Break sollte man jedoch nicht verwenden da es zwar unter modernen Windows keine Funktion mehr hat,
rem jedoch unter umst änden seltsame Nebeneffekte auslösen kann. darum call> zum Leeren der Datei
rem die Quoted Befehlszeile funktioniert nur im in-Block und erspart das Maskieren von Sonderzeichen
for /f "delims=" %%i in ('"type "%textFile%" &call> "%textFile%""') do (
set "line=%%i"
rem weil meine textdatei wahrscheinlich auch Ausrufezeichen enthält, kommen wie oauch ohne verzögerte Expansion zum Ziel
rem ok ...ich hasse diese Prozent-Exzesse auch da wird man ganz schnell Besoffen...
rem ich bin kein Fan von vorangestellten Umleitungen Call set entfernt >>jedoch in diese Konstelation
>>"%textFile%" call echo:%%line:%search%=%replace%%%%
)
pause
es gibt auch eine Variante ohne das man Klammern Maskieren muss...
die Ausgabe darf nicht innerhalb von Klammern erfolgen. Also raus damit, in eine Subroutine....
@echo off
rem oder man lagert den klammerempfindlichen Teil im eine Subroutine aus, und damit außerhalb des Klammerblocks
rem , da dürfte die sicherste Variante sein, denn ein kleines Carret^ hat man schnell mal übersehen
set "search=)"
set "replace=:(test"
set "textFile=test.txt"
for /f "tokens=*" %%i in ('"type "%textFile%" &call> "%textFile%""') do (call :changeLine "%%i" >>"%textFile%")
pause
exit /b
:changeLine %~1 string
set "line=%~1"
call echo:%%line:%search%=%replace%%%%
exit /b
die Testdatei:
hallo
(das ist ein test:)
und ich will meine Ausrufezeichen behalten!
Ich habe mal versucht dein Skript so nachzubauen, dass leere Zeilen, auch solche die erst nach der Ersetzung leer sind, korrekt beibehalten werden. (Dafür ist der Umweg mit findstr notwendig. Das Löschen der alten Datei erledige ich erst hinterher, kannst du aber natürlich auch schon am Beginn der for-Schleife machen.)
@echo off&setlocal enableDelayedExpansion
set "search=i"
set "replace=j"
set "file=file.txt"
for /f "tokens=1* delims=:" %%h in ('findstr /n /r "^" "%file%"') do (
set "line=%%i"
if "!line!"=="" (
echo+
) else (
set "line=!line:%search%=%replace%!"
echo.!line!
)
) >>"_%file%"
del "%file%"
ren "_%file%" "%file%"
leider hat auch dein set-Replace das Klammerproblem, ganz abgesehen davon das normale Texte auch Ausrufezeichen enthalten können 😲
..stirbt auch an der nackten Klammer, wenn set "search=)"