hallöchen.
ich habe eine frage über eine batchverarbeitung.
ich möchte mit dem "for" befehl ein dateiname aus einer .txt datei
auslesen, den string bearbeiten und danach wider in eine zweite
txt.datei abspeichern.
wie könnte man das realisieren?
der "for befehl" akzeptiert irgendwie nur ein befehl welcher an der
ausgelesenen datei angewandt wird....
danke für die hilfe
Gruss
Führt einen Befehl für jede einzelne Datei für einen Satz von Dateien
aus.
FOR %Variable IN (Satz) DO Befehl [Parameter]
%Variable Ein ersetzbarer Parameter bestehend aus einem einzelnen
Buchstaben.
(Satz) Ein Satz von mindestens einer Datei. Platzhalter sind
zulässig.
Befehl Befehl, der für jede Datei ausgeführt werden soll.
Parameter Parameter und Optionen für den angegebenen Befehl.
Um den FOR-Befehl in einem Batchprogramm zu verwenden, geben Sie
%%Variable
statt %Variable an. Beachten Sie die Groß-/Kleinschreibung bei
Variablen-
namen, %i und %I sind nicht identisch.
Wenn die Befehlserweiterungen aktiviert sind, werden folgende
Ergänzungen für den FOR-Befehl unterstützt:
FOR /D %Variable IN (Satz) DO Befehl [Parameter]
Wenn der Satz Platzhalter enthält, dann bezieht sich der FOR-Befehl
auf Verzeichnisse und nicht auf Dateien.
FOR /R [[Laufwerk:]Pfad] %Variable IN (Satz) DO Befehl [Parameter]
Wenn du dir eine Menge Ärger sparen willst, lass Batch sein und verwende
sh, Perl, Ruby, PowerShell, JScript, oder irgend eine andere halbwegs
verständliche Scriptsprache.
Hier wirds erst interessant: (Bei Tokens):
tokens=x,y,m-n - Gibt an, welche Token von jeder Zeile an die
FOR-Schleife weitergegeben werden.
Das führt dazu, dass zusätzliche Variablen
erzeugt
werden. Mit der Form m-n wird dabei ein
Bereich vom
m-ten bis zum n-ten Token angegeben. Wenn das
letzte
Zeichen ein Sternchen ist, wird eine
zusätzliche
Variable deklariert, die den verbleibenden
Text
dieser Zeile enthält.
usebackq - Gibt an, dass die neue Semantik in Kraft ist,
wobei eine Zeichenkette in umgekehrten
Anführungs-
zeichen als Befehl ausgeführt wird und eine
Zeichenkette in Anführungszeichen ein
literaler
Befehl ist, der die Verwendung von doppelten
Anführungszeichen um Dateinamen in
Dateinamens-
sätzen erlaubt.
Einige Beispiele:
FOR /F "eol=; tokens=2,3* delims=, " %i in (Datei.txt) do @echo %i %j %k
Dadurch wird jede Zeile in der Datei Datei.txt ausgewertet, Zeilen
die
mit einem Semikolon beginnen werden ignoriert, für den 2. und 3.
Token
jeder Zeile werden die Befehle in der FOR-Schleife ausgeführt.
Trenn-
zeichen sind Kommas und/oder Leerzeichen. In der FOR-Schleife wird
der
Ausdruck %i verwendet, um den 2. Token zu erhalten, %j für den 3.
Token
und %k, um alle übrigen Token zu erhalten. Dateinamen, die
Leerzeichen
enthalten, müssen Sie innerhalb doppelter Anführungszeichen angeben.
Dazu
müssen Sie die Option "usebackq" verwenden. Andernfalls werden
doppelte
Anführungszeichen zur Definition eines auszuwertenden Literals
verwendet.
Dabei ist %i explizit deklariert, während %j und %k implizit durch
die
Option "tokens=" deklariert werden. Sie können bis zu 26 Token durch
diese
Option angeben, vorausgesetzt, es wird dadurch nicht versucht, eine
Variable mit einem Buchstaben größer als 'z' zu deklarieren.
Bedachten
Sie, dass FOR-Variablen aus nur einem Buchstaben bestehen,
Groß-/Klein-
schreibung beachtet werden muss, dass sie global sind und nicht mehr
als
insgesamt 52 gleichzeitig aktiv sein dürfen.
Sie können den Befehl FOR /F auch direkt mit einer Zeichenkette
verwenden,
indem Sie die Zeichenkette in doppelten Anführungszeichen als
Dateiensatz
zwischen den Klammern angeben. Diese Zeichenkette wird dabei als
einzelne Zeile einer Datei betrachtet und ausgewertet.
Schließlich können Sie den Befehl FOR /F auch verwenden, um die
Ausgabe
eines Befehls auszuwerten. Dazu geben Sie eine Zeichenkette in
einfachen
Anführungszeichen als Dateiensatz zwischen den Klammern an. Diese
Zeichenkette wird dabei als Befehlszeile betrachtet und von einer
unter-
geordneten CMD.EXE ausgeführt. Die Ausgabe dieses Befehls wird dann
wie
eine normale Datei ausgewertet. Das folgende Beispiel listet die Um-
gebungsvariablen im aktuellen Verzeichnis auf:
FOR /F " usebackq delims==" %i IN ((`set`) DO @echo %i
Zusätzlich wurde die Ersetzung von Verweisen auf FOR-Variablen
erweitert.
Sie können jetzt folgende Syntax verwenden:
%~I - Expandiert %I und entfernt alle umschließenden
Anführungszeichen (").
%~fI - Expandiert %I zu einem vollständigen Dateinamen.
%~dI - Erzeugt nur den Laufwerkbuchstaben von %I.
%~pI - Erzeugt nur den Pfad von %I.
%~nI - Erzeugt nur den Dateinamen von %I.
%~xI - Erzeugt nur die Dateierweiterung von %I.
%~sI - Erzeugter Pfad enthält nur kurze Dateinamen.
%~aI - Erzeugt die Dateiattribute von %I.
%~tI - Erzeugt Datum und Zeit von %I.
%~zI - Erzeugt die Dateigröße von %I.
%~$PATH:I - Durchsucht die in der PATH-Umgebungsvariablen
angegebenen Verzeichnisse und expandiert die erste
gefundene Datei %I zu dem vollständigen Dateinamen.
Wenn der Name der Umgebungsvariablen nicht definiert
ist oder diese Datei bei der Suche nicht gefunden
wurde,
wird dieser Parameter zu einer leeren Zeichenkette
expandiert.
Diese Parameter können auch miteinander kombiniert werden:
%~dpI - Erzeugt den Laufwerkbuchstaben und Pfad von %I.
%~nxI - Erzeugt den Dateinamen und die Dateierweiterung von
%I.
%~fsI - Expandiert %I zu einem vollständigen Namen, der nur
kurze Dateinamen enthält.
%~dp$PATH:I - Durchsucht die in der PATH-Umgebungsvariablen
angegebenen Verzeichnisse nach %I und erzeugt den
Laufwerkbuchstaben und Pfad der ersten gefundenen
Datei.
%~ftzaI - Expandiert %I zu einer Zeile, die der Ausgabe des DIR-
Befehls entspricht.
In den angegebenen Beispielen können %I und PATH durch andere gültige
Werte ersetzt werden. Der Ausdruck %~ wird durch einen gültigen
Variablen-
namen für FOR abgeschlossen. Die Verwendung von Großbuchstaben für die
Namen
von Variablen, wie z.B. %I, macht diese Ausdrücke leichter lesbar und
vermeidet Verwechslungen mit den eigentlichen Parametern.
einen informativen Hilfetext. Der Schnippsel zum modifizierten Beispiel
1
FOR /F "eol=; tokens=2,3* delims=, " %i in (Datei.txt) do @echo %i
könnte für dich interessant sein. Wenn die Datei.txt z.B. diese Zeilen
enthält
1
; irgendwas
2
irgendwas name1.txt name2.txt name3.txt
3
irgendwas namea.txt nameb.txt namec.txt
wird mit obigem for-Befehl
name1.txt
namea.txt
ausgegeben, d.h. aus Datei.txt wird bereits was rausgeschnippelt.
Statt %i mit echo auszugeben, könntest du %i auch bearbeiten. Beim
for-Befehl sind ein paar Möglichkeiten angegeben, die jeweils mit %~
eingeleitet werden z.B. Zeit, Datum, voller Pfad usw. bestimmen.
mein Problem ist eben etwas komplex:
Ich habe ien verzeichnis. in diesem sind folgende dateien
enthalten:(beispiele)
7853E1.TXT (1Kb)
7853D0.TXT (1Kb)
7853K0.TXT (2Kb)
5853E1.TXT (150Kb)
5853D0.TXT (150Kb)
5853K0.TXT (2Kb)
7893E1.TXT (130Kb)
7893D0.TXT (130Kb)
7893K0.TXT (2Kb)
ETC...
Es gehören jeweils immer 3 dateien zusammen: eine mit "E1" eine mit "D0"
und eine mit "K0" am ende.
(diese drei dateien bilden einen datensatz einer maschine welche daten
aufzeichnet. wobei E1 und D0 physikalisch grössen beinhalten und K0 nur
kopfdaten)
ich möchte alle datensätze löschen welche kleiner als 4kb sind, dass
sind nähmlich fehlaufzeichnungen welche wenig daten enthalten. soweit
noch kein problem:
grösse von ...E1.txt bzw ...D0.txt Dateien abfragen und je nachdem per
IF entscheidung löschen oder nicht.
Die kopfdatei hat allerdings immer die selbe grösse (2Kb) und kann
deshalb nicht auf diese weise überprüft und gelöscht werden. Denn auch
die Kopf dateien von ordentlichen datensätzen sind nur 2kb.
also muss ich beim löschen einer datendatei, dessen dateiname
(beispiel:7853E1.TXT ) erfassen, das präfix "E1" durch K0 ersetzen und
kann somit die dazugehörende Kopfdatei ermitteln und ebenfall entfernen.
-->7853E1.TXT wird zu 7853K0.TXT
alternativ könnte man den stringteil E1.TXT auch einfach entfernen und
nach 7853*.txt suchen, den der Dateiname vor dem präfix ist einmalig.
Ich hoffe Ich konnte einigermassen vertändlich mein problem erklären.
gruss
und danke
Im Listing nur die relevanten Dateien nämlich *E1.TXT ausgeben lassen.
Davon die Grösse bestimmen. Dann die Nummer im Dateinamen holen. Z.B.
mit obigem for-Befehl, wenn delims=E ist. Daraus die Namen der D0 und K0
Datei erzeugen und dann die auch löschen.
Wenn z.B. eine zu löschende Serie 7893... feststeht dieses im Batch
aufrufen:
SET DATEINAME=7893E1.TXT
@FOR /F "tokens=1 delims=E" %%i in ("%DATEINAME%") do @echo Loesche
%%iK0.txt %%iD0.TXT
Statt der globalen Variablen DATEINAME geht natürlich auch ein Parameter
für die Batchdatei. Oder du ergänzt die Batchdatei, in der die
Grössenauswertung gemacht wird.
der ansatz gefällt mir.... aber
delims "E" geht aber nicht, weil in wirklichkeit auch alphanumerische
zeichen im Dateinamen vorkommen können...
hier einige beispiele von dateisätzen wie sie wirklich aussehen, die
anderen dienten lediglich als Beispiel...
614707_VORB-HVT_212916_FEO-SEIL_26.06.2007_080_3_021D0.TXT
614707_VORB-HVT_212916_FEO-SEIL_26.06.2007_080_3_021E1.TXT
614707_VORB-HVT_212916_FEO-SEIL_26.06.2007_080_3_021K0.TXT
auch ist die länge des dateinamens variabel, man kann also nicht "n"
Zeichen von links auslesen...
deshalb dachte ich an die möglichkeit die Endungen D0.TXT und E1.TXT zu
entfernen und in einem weiteren schritt den restlichen string zeile für
zeile auslesen und so zu extrahieren...
aber ich weiss nicht wie man die weg bekommt...
Welche Buchstaben können noch vorkommen? Wenn VORB-HVT und FEO-SEIL
konstant sind...
Delimiter auf K setzen und den Grundnamen aus
614707_VORB-HVT_212916_FEO-SEIL_26.06.2007_080_3_021K0.TXT holen. Daraus
den E1 Namen bilden und Grössenvergleich machen.
es können alle buchstaben vorkommen, A-Z sowie Ziffern 1-9 und _ und
blanks.
Ansonsten checke mal dieses Batch (ab Win2K) ;-)
@SET
DATEINAME=614707_VORB-HVT_212916_FEO-SEIL_26.06.2007_080_3_021E1.TXT
@SET X=%DATEINAME:E1.TXT=K0.TXT%
@SET Y=%DATEINAME:E1.TXT=D0.TXT%
@echo %DATEINAME% %X% %Y%
so wollte ich das auch in etwa machen. aber dan müsste man zwei befehle
in der for schleife ausführen:
for /f "delims=" %%a in (H:\namenliste.txt) do set X=%a:D0.TXT=K0.TXT%
so wäre der geänderte dateiname zwar in der variable x aber ich kann x
ja nicht mehr ausgeben und nach der for schlaufe ist %%a nicht mehr
gültig....
ich weiss nicht mehr wweiter...
Du machst es gerne kompliziert, oder ;-) Was hindert dich in der
for-Schleife ein weiteres Batchfile zu starten?
Du beschaffst dir eine Liste mit den *.E1.TXT Namen. Du prüfst jeden
Namen aus der Liste auf die Grösse der Datei. Mit den Namen der kurzen
Dateien fütterst du ein sèperates Löschbatch. Im Löschbatch baust du dir
aus dem Namen des übergebenen Arguments (= Name E1 Datei) über die SET
Variante die Namen der K0 und die D0 Datei. Alternativ fütterst du das
2. Batch mit jedem Namen und prüfst dort. Alle drei Dateien löschst du.
Fertisch.
BTW. Ich habe ab JETZT 2 Wochen Urlaub, ich drücke dir die Daumen ;-)