compane
Goto Top

Suchen ersetzen per batch in einer TXT

Servus Zusammen

mal eine denke ich mal einfache Frage:

Ich habe eine TXT-Datei die so aussieht:


Datei C:\temp\test.txt
hallo
hello
Datei C:\temp\test2.txt
hallo
hello

aus dieser möchte folgendes entfernen:

Datei C:\temp\


damit es dann so aussieht:

test.txt
hallo
hello
test2.txt
hallo
hello

Es wäre super wenn ihr mir mal wieder halfen könntet! face-wink

Grüße

Compane

Content-Key: 92638

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

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

Member: bastla
bastla Jul 22, 2008, updated at Oct 18, 2012 at 16:36:00 (UTC)
Goto Top
Hallo Compane!

Da Du anscheinend diesen Beitrag nicht selbst gefunden hast, eine angepasste Version:
@echo off & setlocal enabledelayedexpansion
set "Datei=D:\test.txt"  
set "Von=Datei C:\temp\"  
set "Nach="  

set "t=%temp%\text.tmp"  
if exist "%t%" del "%t%"  
for /f "usebackq delims=" %%i in ("%Datei%") do set "Line=%%i" & set "Line=!Line:%Von%=%Nach%!" & >>"%t%" echo !Line!  
move "%t%" "%Datei%"  

Grüße
bastla

[Edit] Anführungszeichen bei zweitem "set Line=" ergänzt [/Edit]
Member: Compane
Compane Jul 22, 2008 at 12:45:14 (UTC)
Goto Top
Grüße bastla

ich habe ihn schon gefunden bin aber nicht daraus schlau geworden face-sad

Und bin es irgendwie immer noch nicht face-sad

Kannst du mir da mal helfen
Member: bastla
bastla Jul 22, 2008 at 12:52:23 (UTC)
Goto Top
Hallo Compane!

Wo liegt das Problem?

Du gibst in den ersten 3 "set"-Zeilen die Datei, den zu ersetzenden und den Ersatzbegriff (in diesem Fall hier eben gar nix) an.

Mittels "for"-Schleife wird jede Zeile der Datei gelesen, innerhalb der Zeile die Ersetzung vorgenommen (Info dazu: "set /?") und die neue Zeile in eine Temp-Datei geschrieben.

Am Ende ersetzt die Temp-Datei die Ausgangsdatei.

Einschränkung: Wenn in den Zeilen "!" enthalten sind, müsste entweder mit einem Unterprogramm oder mit Einbeziehung von VBScript gearbeitet werden.

Grüße
bastla

P.S.: Ich habe noch 2 Anführungszeichen oben nachgetragen ...
Member: Fuddler
Fuddler Jul 24, 2008 at 16:17:05 (UTC)
Goto Top
Hi bastla,

geniale Lösung!

Ein Wunsch von mir: es wäre schön, wenn Leerzeilen ebenfalls mitkopiert würden.
Geht das irgendwie (bei WinXP/Dos)?

Grüße,
Fuddler
Member: bastla
bastla Jul 24, 2008 at 16:29:11 (UTC)
Goto Top
Hallo Fuddler und willkommen im Forum!

Das sollte dann etwa so gehen:
@echo off & setlocal enabledelayedexpansion
set "Datei=D:\test.txt"  
set "Von=Datei C:\temp\"  
set "Nach="  

set "t=%temp%\text.tmp"  
if exist "%t%" del "%t%"  
for /f "delims=" %%i in ('findstr /n $ "%Datei%"') do set "Line=%%i" & call :ProcessLine  
move "%t%" "%Datei%"  
goto :eof

:ProcessLine
for /f "tokens=1* delims=:" %%a in ("%Line%") do set "L=%%b"  
if not defined L >>"%t%" echo\& goto :eof  
>>"%t%" echo !L:%Von%=%Nach%!  
goto :eof
Und ja, die letzte Zeile ist überflüssig face-wink (zumindest, solange keine weiteren Zeilen hinzugefügt werden).

Grüße
bastla
Member: Fuddler
Fuddler Jul 24, 2008 at 17:57:17 (UTC)
Goto Top
Hi Bastla,

nochmals genial!!! Hab ich bislang im Internet noch nicht gefunden! Vielen Dank dafür!
Hab mir erlaubt den Code noch auf 2 oder mehrere Suchen/Ersetzen-Strings aufzupimpen.

Guckst Du: (Ich hoffe, ich formatier das jetzt hier richtig...)

@echo off & setlocal enabledelayedexpansion
set "Datei=Test.txt"   
set "t=Temp.tmp"   

set "Suchen1=aaa"  
set "Ersetzen1=bbb"  
set "Suchen2=ccc"  
set "Ersetzen2=ddd"  

if exist "%t%" del "%t%"  
for /f "delims=" %%i in ('findstr /n $ "%Datei%"') do set "Line=%%i" & call :ProcessLine  
move "%t%" "%Datei%"  
goto :WEITER_IM_BATCH

:ProcessLine
for /f "tokens=1* delims=:" %%a in ("%Line%") do set "L=%%b"  
if not defined L >>"%t%" echo\& goto :eof  
set WriteLine1=!L:%Suchen1%=%Ersetzen1%!
set WriteLine2=!WriteLine1:%Suchen2%=%Ersetzen2%!
>>"%t%" echo !WriteLine2!  
goto :eof

:WEITER_IM_BATCH
.......

Grüße, Fuddler

EDIT: "@echo off & setlocal enabledelayedexpansion" nachgetragen
EDIT: "Test.text"->"Test.txt" und "copy" -> "move"
Member: bastla
bastla Jul 24, 2008 at 18:54:51 (UTC)
Goto Top
Hallo Fuddler!

Noch eine Frage: Warum verwendest Du "copy" anstatt "move"? Falls Du eine Sicherungskopie erstellen möchtest, solltest Du das besser vor dem Ersetzen machen - so hast Du nur zweimal die veränderte Datei ...

Grüße
bastla
Member: Fuddler
Fuddler Jul 24, 2008 at 19:35:10 (UTC)
Goto Top
Hi Bastla,

hast recht! War nur noch wegen "Debugging" drinface-smile

Hab's editiert....

Grüße,
Fuddler
Member: maracapuccino
maracapuccino Jul 30, 2008 at 13:03:59 (UTC)
Goto Top
Dieses Forum ist wirklich erstaunlich.
Dieser Beitrag ist passt schon wunderbar, aber...

Ich benötige mehr als 2 oder 3 "Suchen und Ersetzen Strings". Daher würde ich gerne an diese Batch eine Input Datei übergeben in der z.B Semikolon getrennt die Suchen und Ersetzen Strings stehen.

AlterString1;NeuerString1
AlterString2;NeuerString2
AlterString3;NeuerString3

Diese Datei kann bis zu 1000 Einträge enthalten.
Nicht jeder "alteString" ist in der Ursprungsdatei enthalten, dann soll einfach mit der nächsten Zeile weitergemacht werden. ( Es werden mehrere Quelldateien bearbeitet, in jeder können unterschiedliche "alte Strings" vorkommen.) Der String kann auch mehrfach vorkommen.
In der Quelldatei können die gesuchten Strings beliebig im Text verteilt sein. Es gibt keinen festen Zeilenaufbau.

z.B (Quelltext auszugsweise, ersetzt werden jeweils die Strings hinter "Objektname")

---text-----
Description = ""
components = List
{
AIPD01ref7 = *AIPD01.de
{
ports::UnitColor = "K15"
ports::NormalColor = "K15"
ports::CycleTime = "3s"
ports::ObjectName = "QI11.10ITS"
}
wsDIIndText1ref36 = *wsDIIndText1.de
{
ports::FrameYSize = 1
ports::CycleTime = "3s"
ports::FrameWidth = 1
ports::OffColor = "A11"
ports::OffText = "ATN"
ports::OnColor = "L1"
ports::OnText = "ATN"
ports::ObjectName = "QI11.21ATN"
ports::TextFont = "FC10"
ports::FrameXSize = 3
ports::BackColor = "A1"
ports::ConditionCycle = "onRequest+onEvent"
}
wsDIIndText1ref35 = *wsDIIndText1.de
{
ports::FrameYSize = 1
ports::CycleTime = "3s"
ports::FrameWidth = 1
ports::OffColor = "A11"
ports::OffText = "ATN"
ports::OnColor = "L1"
ports::OnText = "ATN"
ports::ObjectName = "QI11.20ATN"
ports::TextFont = "FC10"
ports::FrameXSize = 3
ports::BackColor = "A1"
ports::ConditionCycle = "onRequest+onEvent"
noch mehr text--------- }


Ich bin damit leider überfordert, und für jede Hilfe dankbar.

Grüße MaraCapuccino
Member: bastla
bastla Jul 30, 2008 at 14:32:02 (UTC)
Goto Top
Hallo maracapuccino und willkommen hier im (erstaunlichen face-wink) Forum!

Das könnte so gehen (und ich meine "gehen", denn bei 1000 Ersetzungspaaren gehe face-wink ich nicht von "laufen" aus):
@echo off & setlocal enabledelayedexpansion
set "Datei=D:\Test.txt"  
set "Liste=D:\Ersetzungsliste.txt"  

set "t=%temp%\text.tmp"  
if exist "%t%" del "%t%"  
for /f "delims=" %%i in ('findstr /n $ "%Datei%"') do set "Line=%%i" & call :ProcessLine  
move "%t%" "%Datei%"  
goto :eof

:ProcessLine
for /f "tokens=1* delims=:" %%a in ("%Line%") do set "L=%%b"  
if not defined L >>"%t%" echo\& goto :eof  
for /f "usebackq tokens=1-2 delims=;" %%s in ("%Liste%") do set "L=!L:%%s=%%t!"  
>>"%t%" echo %L%  
goto :eof
Für die Datei "Ersetzungsliste.txt" wird, wie in Deinem Vorschlag oben, ";" als Trennzeichen zwischen altem und neuem Wert verwendet - sollte das Semikolon in einem der Werte selbst vorkommen, müsstest Du ein anderes Trennzeichen suchen und in der Datei und in Zeile 14 des Batches (nach "delims=") verwenden.

Grüße
bastla
Member: maracapuccino
maracapuccino Jul 30, 2008 at 17:31:05 (UTC)
Goto Top
Hallo bastla

Hat super funktioniert. Du hast allerdings recht, bei vielen Ersetzungen dauert das.

Ich habe lange gebraucht um die Batch zu verstehen. Ich habe sie mit Logausgaben gespickt !!!
Gerade die "Token Befehle" sagen mir nicht viel. Auch
"usebackq" wäre erklärungsbedürftig.

Möglicherweise ist das Basiswissen, aber wieso steht in der
Variable %%t der Ersetzungsstring ? Weil "t" alphabetisch nach "s" kommt ? Kann man den Inhalt solcher Variablen in eine Logdatei ausgeben ?

Ansonsten hast du mir sehr weitergeholfen.

Gruß
MaraCapuccino
Member: bastla
bastla Jul 30, 2008 at 18:03:03 (UTC)
Goto Top
Hallo maracapuccino!

Gerade die "Token Befehle" sagen mir nicht viel.
Sieh Dir dazu die Onlinehilfe an:
for /?

Auch "usebackq" wäre erklärungsbedürftig.
In einer "for /f"-Schleife wird der Inhalt der Klammer, wenn er unter doppelten Anführungszeichen steht, als Text interpretiert. Da ich zur Vorsicht neige und daher grundsätzlich Pfadangaben unter Anführungszeichen setze, muss ich mit "usebackq" den Interpreter darüber informieren, dass der zwischen den Anführungszeichen stehende Teil doch wieder als Dateiname zu verstehen ist. Wenn Du sicher bist, dass im Pfad und Dateinamen zur Ersetzungsliste keine Leerzeichen vorkommen werden, kannst Du auf "usebackq" verzichten und in der Klammer einfach %Liste% schreiben.

Möglicherweise ist das Basiswissen, aber wieso steht in der Variable %%t der Ersetzungsstring ? Weil "t" alphabetisch nach "s" kommt ?
So ist es.

Kann man den Inhalt solcher Variablen in eine Logdatei ausgeben ?
Wie für jede andere Variable kannst Du einfach ein "echo" verwenden:
echo %%s %%t>>D:\Logdatei.txt
Und solltest Du Dich darüber wundern, dass ich eine solche Umleitung zB im Batch oben bereits vor dem "echo" schreibe: Diese Variante habe ich (wie so Vieles, was ich über Batch weiß), erstmals hier im Forum, und da natürlich bei Biber gesehen. Sinn des Ganzen ist, zu vermeiden, dass etwa bei der Ausgabe einer Variablen mit dem Inhalt "Stockwerk: 2" mit
echo %Var%>>Textdatei.txt
aufgelöst
echo Stockwerk: 2>>Textdatei.txt
entsteht, was zu einem "Verschlucken" der Ausgabe führen würde, da "2>>" als Umleitung von Fehlermeldungen interpretiert wird, es aber bei diesem "echo" gar keinen Fehler gibt, sodass auch nichts geschrieben werden muss. Mit
>>Textdatei.txt echo %Var%
passiert das nicht.

Grüße
bastla
Member: maracapuccino
maracapuccino Aug 01, 2008 at 19:05:56 (UTC)
Goto Top
Hallo bastla,
Vielen Dank für die wirklich sehr ausführliche und verständliche Auskunft.
Ich hoffe, ich kann eines Tages auch mal irgendjemandem so gut weiterhelfen.

Gruss maracapuccino