Batch-Datei zur Erzeugung von Textdateien (basierend auf einer Ausgangsdatei) je nach Inhalt des Verzeichnisses, for-Schleifen-Problem
Hallo zusammen,
da ich hier schon ein paar hilfreiche Tipps gefunden habe, die mich der Lösung meines Problems näher gebracht haben, hoffe ich, dass mir jemand von euch auch noch bei dem Rest helfen kann.
Ich schreibe an einer Batch-Datei, mit deren Hilfe Verbindungsdateien für lokale Datenbanken (Firebird) je nach Inhalt des Datenbankordners erstellt werden sollen.
Als Vorlage hierfür dient eine vorhandene Verbindungsdatei im txt-Format.
Die Batchdatei sieht folgenden Ablauf vor:
Zunächst wird eine txt-Datei (datenbanken.txt) erstellt, welche die Dateinamen aus dem Datenbank-Ordner auflistet. Danach wird die Ausgangs-Verbindungsdatei kopiert und in eine txt umgewandelt und umbenannt (neuedsn.txt). Nun soll für jede Zeile in datenbanken.txt ein bestimmter Eintrag in neuedsn.txt gesucht und durch die Zeile aus der datenbanken.txt ersetzt werden. Das ganze wird dann in eine neue Datei gespeichert, wieder in eine Verbindungsdatei umgewandelt und zurückkopiert (in den Ordner mit den Verbindungsdateien).
Soweit so gut, allerdings wirft mir meine Batch-Datei in der Konsole einen Syntaxfehler aus. Ich bin mir relativ sicher, dass es an der ersten for-Schleife (für die Abarbeitung der einzelnen Zeilen in der datenbanken.txt) liegt. Den Suchen-und-Ersetzen Teil habe ich so aus dem Netz kopiert und der funktionierte einzeln (aber ohne die Variable %%f in ausgabe und ersetzungszeichen) wunderbar.
Hier mein Quelltext:
In einem weiteren Schritt sollte noch der Inhalt der vorherige datenbanken.txt (also vor dem löschen) mit C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\ abgeglichen werden und Dateien, die mit den EIntragungen in der txt übereinstimmen gelöscht werden.
Ich würde mich sehr freuen, wenn ihr hierbei auch helfen könntet.
Liebe Grüße,
Christiane
da ich hier schon ein paar hilfreiche Tipps gefunden habe, die mich der Lösung meines Problems näher gebracht haben, hoffe ich, dass mir jemand von euch auch noch bei dem Rest helfen kann.
Ich schreibe an einer Batch-Datei, mit deren Hilfe Verbindungsdateien für lokale Datenbanken (Firebird) je nach Inhalt des Datenbankordners erstellt werden sollen.
Als Vorlage hierfür dient eine vorhandene Verbindungsdatei im txt-Format.
Die Batchdatei sieht folgenden Ablauf vor:
Zunächst wird eine txt-Datei (datenbanken.txt) erstellt, welche die Dateinamen aus dem Datenbank-Ordner auflistet. Danach wird die Ausgangs-Verbindungsdatei kopiert und in eine txt umgewandelt und umbenannt (neuedsn.txt). Nun soll für jede Zeile in datenbanken.txt ein bestimmter Eintrag in neuedsn.txt gesucht und durch die Zeile aus der datenbanken.txt ersetzt werden. Das ganze wird dann in eine neue Datei gespeichert, wieder in eine Verbindungsdatei umgewandelt und zurückkopiert (in den Ordner mit den Verbindungsdateien).
Soweit so gut, allerdings wirft mir meine Batch-Datei in der Konsole einen Syntaxfehler aus. Ich bin mir relativ sicher, dass es an der ersten for-Schleife (für die Abarbeitung der einzelnen Zeilen in der datenbanken.txt) liegt. Den Suchen-und-Ersetzen Teil habe ich so aus dem Netz kopiert und der funktionierte einzeln (aber ohne die Variable %%f in ausgabe und ersetzungszeichen) wunderbar.
Hier mein Quelltext:
@echo off
rem Löschen der alten DB-Liste
del d:\sw\datenbanken.txt
rem Erstellen der neuen DB-Liste
for /f "delims=" %%i in ('dir d:\sw\db\*.gdb /b') do @echo %%~ni >> d:\sw\datenbanken.txt
rem Kopieren der Lokal-dsn nach d:\sw
xcopy /q /y "C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\lokal_D.dsn" d:\sw\
rem Umbenennen der dsn in txt
ren d:\sw\lokal_D.dsn neuedsn.txt
rem Erstellen der neuen dsn-Files
for /f "delims=" %%f in (d:\sw\datenbanken.txt) do (
REM Ersetzen des DBNamen in der dsn
SETLOCAL enabledelayedexpansion
SET "datei=d:\sw\neuedsn.txt"
SET "ausgabe=d:\sw\%%f.txt"
SET "suchzeichen=sw.gdb"
SET "ersetzungszeichen=%%f.gdb"
REM Datei zeilenweise auslesen
REM und in Variable "zeile" schreiben
FOR /f "delims=" %%j IN ('FINDSTR . "%datei%"') DO (
SET zeile=%%j& CALL :ersetzen !zeile!
)
GOTO :eof
:ersetzen
REM Das Suchzeichen mit dem Ersetzungsteichen tauschen
SET zeile=!zeile:%suchzeichen%=%ersetzungszeichen%!
REM Ergebnis in die Ausgabedatei schreiben
ECHO !zeile!>>%ausgabe%
GOTO :eof
:eof
rem Umbenennen der txt in dsn
ren d:\sw\%%f.txt %%f.dsn
rem kopieren der neuen dsn
xcopy /q /y d:\sw\%%f.dsn "C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\"
rem löschen des dsn-files unter d:
del d:\sw\%%f.dsn
)
rem löschen der neuedsn.txt
del d:\sw\neuedsn.txt
In einem weiteren Schritt sollte noch der Inhalt der vorherige datenbanken.txt (also vor dem löschen) mit C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\ abgeglichen werden und Dateien, die mit den EIntragungen in der txt übereinstimmen gelöscht werden.
Ich würde mich sehr freuen, wenn ihr hierbei auch helfen könntet.
Liebe Grüße,
Christiane
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 117398
Url: https://administrator.de/forum/batch-datei-zur-erzeugung-von-textdateien-basierend-auf-einer-ausgangsdatei-je-nach-inhalt-des-verzeichnisses-117398.html
Ausgedruckt am: 06.05.2025 um 23:05 Uhr
12 Kommentare
Neuester Kommentar

Hallo Chistiane,
willkommen im Forum.
Du hast scheinbar einige Codeschnipsel die als SUB realisiert waren einfach in deine Schleife kopiert, das geht so nicht.
Die goto :Eof innerhalb der Schleife lassen die ganze Batchdatei abbrechen und die Label innerhalb der Schleifen funktionieren auch nicht.
Ich muss gerade den Platz wechseln, melde mich nochmal wenn kein anderer schneller ist
Gruß
LotPings
willkommen im Forum.
Du hast scheinbar einige Codeschnipsel die als SUB realisiert waren einfach in deine Schleife kopiert, das geht so nicht.
Die goto :Eof innerhalb der Schleife lassen die ganze Batchdatei abbrechen und die Label innerhalb der Schleifen funktionieren auch nicht.
Ich muss gerade den Platz wechseln, melde mich nochmal wenn kein anderer schneller ist
Gruß
LotPings

Hallo nochmal,
nach einiger Trockenübungs-Gehirnakrobatik bin ich zu dem Schluß gekommen
das die ganze hin und her Kopiererei eigentlich entfallen könnte.
Diese 2 gestaffelten For Schleifen sollten eigentlich den Zweck erfüllen.
Ob die Datenbank.txt überhaupt nötig ist weiß ich nicht, sie wird in einem Rutsch mit
neu erstellt.
Gruß
LotPings
Edit zuviel gekürzt der Setlocal fehlte
Edit2: Ein %-Zeichen fehlte in Zeile 17
Edit3: Alte dsn muss gelöscht werden
nach einiger Trockenübungs-Gehirnakrobatik bin ich zu dem Schluß gekommen
das die ganze hin und her Kopiererei eigentlich entfallen könnte.
Diese 2 gestaffelten For Schleifen sollten eigentlich den Zweck erfüllen.
Ob die Datenbank.txt überhaupt nötig ist weiß ich nicht, sie wird in einem Rutsch mit
neu erstellt.
@echo off
SetLocal EnableDelayedExpansion
rem globale Variablen
SET "Vorlage=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\lokal_D.dsn"
SET "ZielPfad=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\"
SET "suchzeichen=sw.gdb"
rem Löschen der alten DB-Liste
del d:\sw\datenbanken.txt
rem Erstellen der neuen DB-Liste
FOR /f "delims=" %%i in ('dir d:\sw\db\*.gdb /B /ON /A-D') do (
>>"d:\sw\datenbanken.txt" echo/%%~ni
Type NUL>"%ZielPfad%%%~ni.dsn"
FOR /f "delims=" %%j IN ('Type "%Vorlage%" ') DO (
Set "Zeile=%%~j"
>>"%ZielPfad%%%~ni.dsn" Echo/!Zeile:%suchzeichen%=%%~nxi!
)
)
Gruß
LotPings
Edit zuviel gekürzt der Setlocal fehlte
Edit2: Ein %-Zeichen fehlte in Zeile 17
Edit3: Alte dsn muss gelöscht werden

Die Ersetzung funktionierte nicht mit DelayedExpansion, habe hier ein Ersatzkonstrukt, damit gehts.
Gruß
LotPings
Edit: Zeile 8 eingefügt, löscht alle dsn zu Datenbanken.txt
@echo off
rem globale Variablen
SET "SucheZ=sw.gdb"
SET "Vorlage=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\lokal_D.dsn"
SET "ZielPfad=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\"
Set DBMaske=D:\sw\db\*.gdb
Set DBListe=D:\sw\datenbanken.txt
FOR /f "delims=" %%A IN ('Type "%DBListe%" ') Do Del /Q "%ZielPfad%%%A.dsn" >NUL 2>&1
rem Löschen der alten DB-Liste
del %DBListe%
rem Erstellen der neuen DB-Liste
FOR /f "delims=" %%i in ('dir %DBMaske% /B /ON /A-D') do (
>>"%DBListe%" echo/%%~ni
Type NUL>"%ZielPfad%%%~ni.dsn"
FOR /f "delims=" %%j IN ('Type "%Vorlage%" ') DO (
Set "Zeile=%%~j"
>>"%ZielPfad%%%~ni.dsn" Call Echo/%%Zeile:%SucheZ%=%%~nxi%%
)
)
Wäre super wenn du mir dann den Quellcode innerhalb der Schleifen auch nochmal genauer erklären könntest. 
- Die Äußere Schleife von Zeile 13 bis 20 listet die Datenbanken in %%i auf,
- Z14 fügt sie der datenbanken.txt hinzu.
- Z15 löscht den Inhalt der jeweiligen alten dsn oder erstellt sie neu.
- Die innere For Schleife von Z16 bis Z19 liest die Vorlage Zeile für Zeile in %%j
- Da die Ersetzung nicht direkt in einer Schleifenvariable stattfinden kann kopiert Z17 %%j in %Zeile%
- Z18 hängt die bearbeitet Zeile an die neue .dsn an. Damit keine Leerzeichen am Ende der Zeile mitgeschriebene werden steht der Append vorne. Der Pseudo Call sorgt dafür das im ersten Schritt die Suchen/Ersetzen Werte aufgelöst werden und erst im zweiten Schritt die verdoppelten Prozentzeichen um die Variable Zeile.
Gruß
LotPings
Edit: Zeile 8 eingefügt, löscht alle dsn zu Datenbanken.txt

Nein nein, für Helden-Kostüme bin ich zu alt 
Muss mal wiederden Rechner wechseln, poste dann noch mal.
Gruß
LotPings
Meinst du bei dem zweiten Schritt kannst du auch noch helfen? Bzw. lässt sich das überhaupt so realisieren?
Ich habe oben Zeile 8 eingefügt, die sollte das erledigen."In einem weiteren Schritt sollte noch der Inhalt der vorherige datenbanken.txt (also vor dem löschen) mit
C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\
abgeglichen werden und Dateien, die mit den EIntragungen in der txt übereinstimmen gelöscht werden."
Es geht hierbei darum, dass in dem Ordner enige dsn-Files mehr liegen, die die Verbindungsdaten zu verschiedenen Datenbanken auf Servern enthalten und diese nicht gelöscht werden dürfen.
Ok aber dann brauchst du doch nur eine Batch die alle dsn mit lokalen Datenbanken durchorgelt und prüft ob diese noch existieren.C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\
abgeglichen werden und Dateien, die mit den EIntragungen in der txt übereinstimmen gelöscht werden."
Es geht hierbei darum, dass in dem Ordner enige dsn-Files mehr liegen, die die Verbindungsdaten zu verschiedenen Datenbanken auf Servern enthalten und diese nicht gelöscht werden dürfen.
Es ist davon auszugehen, dass der User im Idealfall jedesmal, wenn er sich eine lokale Datenbank erstellt/kopiert/o.ä. die .bat ausführt, also sollten bis dahin in der datenbanken.txt noch der alte Inhalt stehen (tut er ja auch) und dementsprechend sollten alles Datenbankverbindungen, die mit den Namen in der .txt übereinstimmen zuerst gelöscht werden.
Existiert keine datenbank.txt mehr, weil der User sie per Hand entfernt hat = shit happens, heißt die handvoll Datenbankverbindungen, die dann nutzlos rumliegen, sind egal. ;)
Muss ja nicht sein, die beschriebene Prüfung ist ja nicht schwer, zu klären ist welche Pfade lokal möglich sind.Existiert keine datenbank.txt mehr, weil der User sie per Hand entfernt hat = shit happens, heißt die handvoll Datenbankverbindungen, die dann nutzlos rumliegen, sind egal. ;)
Muss mal wiederden Rechner wechseln, poste dann noch mal.
Gruß
LotPings

Als Ergänzung eine Batch Datei die Anhand der in den dsn Dateien enthaltenen Datenbanknamen deren Vorhandensein überprüft.
Eine Einschränkung gibt es, der Findstr Befehl zickt etwas wenn ein Suchbegriff in der letzten Zeile steht und diese nicht mit einem Return abgeschlossen ist.
Noch etwas: wenn der Suchbegriff im Findstr Befehl mit einem Backslash endet, muss ein zweiter Backslash hinzugefügt werden, sonst wird der eine als Escape für das schließende Anführungszeichen betrachtet - das wirft dann Syntaxfehler auf.
Gruß
LotPings
Edit: Wie gewünscht ein paar Erläuterungen.
Gruß
LotPings
Eine Einschränkung gibt es, der Findstr Befehl zickt etwas wenn ein Suchbegriff in der letzten Zeile steht und diese nicht mit einem Return abgeschlossen ist.
:: DelOldDsn.cmd :::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
SET "Vorlage=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\lokal_D.dsn"
SET "ZielPfad=C:\Programme\Gemeinsame Dateien\ODBC\Data Sources\"
Set "DBPfad=D:\sw\db\"
Pushd "%ZielPfad%"
For /F "tokens=1-2* delims=:=" %%A in (
'Findstr /I /L "Dbname=%DBPfad%\" "*.dsn"^|Find /I /V "lokal_d.dsn" '
) do if Not Exist "%%C" Echo Die Datenbank %%C existiert nicht,&Del /P "%%A"
POPD
Noch etwas: wenn der Suchbegriff im Findstr Befehl mit einem Backslash endet, muss ein zweiter Backslash hinzugefügt werden, sonst wird der eine als Escape für das schließende Anführungszeichen betrachtet - das wirft dann Syntaxfehler auf.
Gruß
LotPings
Edit: Wie gewünscht ein paar Erläuterungen.
- Kern der Batch ist der Findstr in Z09, er durchsucht alle dsn Dateien nach dbname=d:\sw\db\ und gibt Fundstellen in dieser Form aus:
Dateiname.dsn:dbname=D:\sw\db\Dateiname.gdb
%%A | %%B | %%C |
Dateiname.dsn | dbname | D:\sw\db\Dateiname.gdb |
- Z10 ist dann eigentlich selbsterklärend. Das & hängt einen weiteren Befehl ohne neue Zeile an.
Gruß
LotPings

Zitat von @Sonnenblume87:
also die Ergänzung mit dem Löschen funktioniert auch wieder super. Ist genau das, so wie es werden sollte.
Schön.also die Ergänzung mit dem Löschen funktioniert auch wieder super. Ist genau das, so wie es werden sollte.
Die zweite Batch-Datei ist ne nette Idee aber leider nicht praktikabel, da in dem Data Sources Ordner auch viele dsn-Files liegen zu denen es keine lokale DB gibt, da es Server-DBs sind. Das würde also zuviel löschen.
Keine Angst, diese Batchdatei nimmt nur dsn die einen Eintrag haben der mit "dbname=D:\sw\db\" beginnt.
Ausserdem wird angezeigt was gelöscht würde und erst nach einer Bestätigung tatsächlich gelöscht.
Insofern kannst du das gefahrlos ausprobieren.
Gruß
LotPings

Zitat von @Sonnenblume87:
Aber magst du mir die 2te Datei nochmal erläutern?
Die meisten Begriffe und die Nutzung der Sonderzeichen sagen mir bisher gar nichts und ehe ich mir jetzt jede help durchlese bzw. mir die Sachen ergoogle,
Aber genau dadurch lernt man selbst am Besten.Aber magst du mir die 2te Datei nochmal erläutern?
Die meisten Begriffe und die Nutzung der Sonderzeichen sagen mir bisher gar nichts und ehe ich mir jetzt jede help durchlese bzw. mir die Sachen ergoogle,
wäre eine programmbezogene Erklärung dann doch besser. 
Siehe oben.Gruß
LotPings