maxuser
Goto Top

Zeilen aus Textdatei auslesen und modifiziert in eine neue Textdatei schreiben

Hallo allerseits,

da ich neu bin grüsse ich zuerst alle MItglieder.

Nun zu meine Frage. Ich möcte gerne ein Batchprgramm schreiben (eine Datei "xxx.bat") der folgendes machen soll.

In eine Quell-Textdatei steht folgender Inhalt

CL08001407
CL08002715
CL08002913
CL08003313

Der Batch soll mir diese vier Zeilen bzw. alle vorhandene Zeilen auslesen und wie folgt in die erste Zeile eines Ziel-TextDatei schreiben

CL08001407|CL08002715|CL08002913|CL08003313

Darf dabei die QuellDatei und die Zieldatei geöffnet sein? Oder müssen beide geschlossen sein?

Will noch hindeuten das ich in Sachen Batchprogrmmierung sehr neu bin. Darum wär für mich hilfreich den möglichen Lösungs-Code von A-Z zu erhalten^^

Content-Key: 108234

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

Printed on: April 18, 2024 at 23:04 o'clock

Member: bastla
bastla Feb 06, 2009 at 08:38:29 (UTC)
Goto Top
Hallo MaxUser und willkommen im Forum!
Der Batch soll mir diese vier Zeilen bzw. alle vorhandene Zeilen auslesen und wie folgt in die erste Zeile eines Ziel-TextDatei schreiben
Diese Anforderung solltest Du noch etwas konkretisieren:
- Sollen nur die 4 Werte in die erste Zeile, oder tatsächlich alle Zeilen zu einer einzigen zusammengefasst werden?
- Wenn nur die angesprochenen 4 Zeilen zu einer zusammngefasst werden sollen: Woran sind diese Zeilen zu erkennen? Beginnen Sie etwa als einzige mit "CL"?
- Und noch eine Frage: sind es immer genau 4 Zeilen?

Darf dabei die QuellDatei und die Zieldatei geöffnet sein?
Soll die Zieldatei denn nicht neu erstellt, sondern eine bereits vorhandene Datei verändert werden?

Grüße
bastla
Member: MaxUser
MaxUser Feb 06, 2009 at 08:52:21 (UTC)
Goto Top
Hallo Bastla,

danke für dein Beitrag.

es sollen alle vorhandene Zeilen zu eine Zeile zusammengefügt werden und mit einen pipe getrennt werden. Das mit den 4 Zeilen war nur ein Beispiel

aus drei vorhandene zeilen

AB
BC
DF

soll folgendes erfolgen

AB|BC|DF

Es wär noch besser wenn das Ergebnis automatisch in die Zwischenablage kopiert wird, da es für ein Filter weiterbenutzt wird.
Ansonsten wär es auch gut wenn das Ergebnis in eine neue Zeile der Quelldatei geschrieben wird. Also die Quelltextdatei würde dann folgend aussehen

AB
BC
DF
AB|BC|DF
Member: bastla
bastla Feb 06, 2009 at 09:49:43 (UTC)
Goto Top
Hallo MaxUser!

Das Zusammenfassen könnte etwa so gehen:
@echo off & setlocal
set "Quelle=D:\Quellordner\Quelldatei.txt"  

set Zeile=
for /f "usebackq delims=" %%i in ("%Quelle%") do call :ProcessLine "%%i"  
>>"%Quelle%" echo\  
>>"%Quelle%" echo %Zeile:~2%  
goto :eof

:ProcessLine
set "Zeile=%Zeile%^|%~1"  
goto :eof
Falls Du vor der zusammengefassten Zeile noch eine Leerzeile erhältst, die Batchzeile 6 weglassen.

Noch ein Hinweis: Sonderzeichen (wie etwa "&", "<", ...) könnten Probleme bereiten (oder müssten zumindest gesondert behandelt werden).

Grüße
bastla

P.S.: Eine Beschreibung des Ablaufes kann ich erst später am Tag nachreichen ...
Member: MaxUser
MaxUser Feb 06, 2009 at 10:08:28 (UTC)
Goto Top
Hi Bastla,

danke für den Code. in der zusammengefassten Zeile bekomme ich jetzt eine Meldung

ECHO ist ausgeschaltet (OFF).

Was muss ich da machen?
Member: bastla
bastla Feb 06, 2009 at 11:09:14 (UTC)
Goto Top
Hallo MaxUser!

Diese Meldung bedeutet, dass keine Daten geschrieben werden konnten - mögliche Gründe:
- die in Zeile 2 angegebene Quelldatei enthält nur Leerzeilen (vermutlich auszuschließen face-wink)
- der Variablenname %Zeile% ist in Zeile 7 des Batches anders geschrieben als in Zeile 11

Grüße
bastla
Member: MaxUser
MaxUser Feb 06, 2009 at 11:31:20 (UTC)
Goto Top
Hallo

habe nochmal den Code in die Batchdatei kopiert.

Jetzt funktioniert es wunderbar.

Vielen Dank und ein schönes Wochenende.
Member: bastla
bastla Feb 06, 2009, updated at Oct 18, 2012 at 16:37:43 (UTC)
Goto Top
Hallo MaxUser!
Jetzt funktioniert es wunderbar.
Freut mich. face-smile

Wie versprochen noch einige Anmerkungen zum Code:
@echo off & setlocal
und
set "Quelle=D:\Quellordner\Quelldatei.txt"
habe ich hier schon mal kurz beschrieben ...

set Zeile=
Eigentlich sollte es die Variable %Zeile% zu Beginn des Batches ohnehin nicht geben - jetzt existiert diese aber ganz sicher nicht face-wink (wird durch diese "Zuweisung" gelöscht).

for /f "usebackq delims=" %%i in ("%Quelle%") do call :ProcessLine "%%i"
Zu den Inhalten dieser Zeile findest Du ebenfalls an anderer Stelle einige Anmerkungen - Sinn dieser Zeile ist es, jede Zeile einzeln auszulesen und an das Unterprogramm ":ProcessLine" am Stück (daher unter Anführungszeichen zu setzen) weiter zu reichen.

>>"%Quelle%" echo\
>>"%Quelle%" echo %Zeile:~2%
Diese beiden Zeilen schreiben eine Leerzeile sowie den Inhalt der Variablen %Zeile% nach dem zweiten Zeichen jeweils an das Ende der Quelldatei (">>" bedeutet "Anfügen", mit ">" würde eine neue Datei erstellt = die bestehende überschrieben). Da die Variable %Zeile% als erste Zeichen "^|" (vom Hinzufügen der ersten Zeile) enthält, kann die Ausgabe erst nach Position 2 erfolgen.

goto :eof
Damit wird ein Batch (und auch ein Unterprogramm kann als "Batch" im "Batch" betrachtet werden - siehe unten) beendet (stellt sicher, dass das danach folgende Unterprogramm nicht ein weiteres - und damit überflüssiges - Mal ausgeführt wird und ist somit die Stelle, an welcher der gesamte Batch beendet wird.

:ProcessLine
set "Zeile=%Zeile%^|%~1"
goto :eof
Dieses Unterprogramm wird für jede Zeile der Quelldatei aufgerufen und stellt eigentlich einen eigenen Batch dar - deshalb kann es auch den (ersten und einzigen) beim Aufruf übergebenen Parameter "Zeileninhalt" als %1 übernehmen.

Verarbeitet wird dieser Parameter, indem an den aktuellen Inhalt der Variablen %Zeile% (beim ersten Aufruf ist diese noch nicht vorhanden und daher "leer") zunächst ein "|" und danach die übergebene Zeile angefügt wird. Mit "%~1" anstelle von "%1" wird der Parameter ohne die umgebenden Anführungszeichen angesprochen.

Mit der Schreibweise "^|" wird das Pipe-Sysmbol "maskiert", was dem Interpreter mitteilt, dass es als gewöhnliches Zeichen und nicht als Verbindung zur nächsten Anweisung zu verstehen ist.

"goto :eof" hat die schon oben beschriebene Funktion, das Ende dieses Programmteiles (und damit hier - in einem Unterprogramm - die Anweisung zum Rücksprung in das Hauptprogramm -konkret in die "for"-Schleife - zu signalisieren). An dieser Stelle des Batches könnte es auch weg gelassen werden, da nach der letzten Batchzeile ein automatisches "goto :eof" ausgeführt wird - da es aber nicht schadet, schreibe ich es sicherheitshalber grundsätzlich hin, um es im Fall des Falles unterhalb das Platzieren weiterer Programmteile zu ermöglichen.

Grüße
bastla