Newbe need help for-schleife
habe die windows hilfe schon duchgeblättert aber komme zu keinem Ziel
Hi @ all
sry das ich so bekloppten sachen frage aber quäle mich schon seit ner weile damit rum und mir fehlen einfach die kenntnise, vernünftige beispiele finde ich leider auch nicht ...
Probelmbeschreibung:
möchte gerne erste spalte einer textdatei(D1),Zeichen sind durch leerzeichen getrennt, mit einer anderen textdatei(D2) vergleichen,
wenn nun der Zeichensatz aus der ersten spalte(D1) in der 1. spalte(D2) nicht vorkommt in die (D2) schreiben notfalls auch erst in eine tmp und später in die (D2)
mein Ansatz war volgender:
weiteres Problem:
Funktion - möchte aus einer datei 3 Parameter auslesen aber einige sind nicht vergeben und sollen übersprungen werden.
wieder ein ansatz von mir
aber jetzt beim tippen fällt mir auf was sein könnte - wenn die erste schleife nichts findet bleibt STRING1 leer und die 2. schleife schreibt in STRING1 (bis hirher is es genau so gewollt)
aber dann wird nicht weiter hochgezählt, da in der letzten zeile geprüft wird ob STRING2 leer ist.
aber wie kann ich das lösen, kann ja nicht schreiben
bitte um hilfe
und bei gelegenheit einige for-schleifen als beispiele mit variablen mit erklärung wär echt super
thx
Hi @ all
sry das ich so bekloppten sachen frage aber quäle mich schon seit ner weile damit rum und mir fehlen einfach die kenntnise, vernünftige beispiele finde ich leider auch nicht ...
Probelmbeschreibung:
möchte gerne erste spalte einer textdatei(D1),Zeichen sind durch leerzeichen getrennt, mit einer anderen textdatei(D2) vergleichen,
wenn nun der Zeichensatz aus der ersten spalte(D1) in der 1. spalte(D2) nicht vorkommt in die (D2) schreiben notfalls auch erst in eine tmp und später in die (D2)
mein Ansatz war volgender:
for /F "tokens=1,2*" %%i in ("%1") do (
if "%%FOUND%%"==0 echo %%LINE%% >> datei.tmp
set FOUND=1
set FIND=%%i
set LINE=%%i %%j
for /F "tokens=1,2*" %%i in (%DATEI%) do (
if "%%FIND%%"=="%%i" set FOUND=1
))
if "%%FOUND%%"==0 echo %%LINE%% >> datei.tmp
set FOUND=1
set FIND=%%i
set LINE=%%i %%j
for /F "tokens=1,2*" %%i in (%DATEI%) do (
if "%%FIND%%"=="%%i" set FOUND=1
))
weiteres Problem:
Funktion - möchte aus einer datei 3 Parameter auslesen aber einige sind nicht vergeben und sollen übersprungen werden.
wieder ein ansatz von mir
set COUNT=1
for /F "tokens=1,2,3*" %%i in (%1) do (
if "TEXT1"=="%%i" do set STRING%%COUNT%%=%%k
)
if not "%STRING1%"=="" SET /a COUNT=%COUNT%+1
for /F "tokens=1,2,3*" %%i in (%1) do (
if "TEXT2"=="%%i" do set STRING%%COUNT%%=%%k
)
if not "%STRING2%"=="" SET /a COUNT=%COUNT%+1
for /F "tokens=1,2,3*" %%i in (%1) do (
if "TEXT1"=="%%i" do set STRING%%COUNT%%=%%k
)
if not "%STRING1%"=="" SET /a COUNT=%COUNT%+1
for /F "tokens=1,2,3*" %%i in (%1) do (
if "TEXT2"=="%%i" do set STRING%%COUNT%%=%%k
)
if not "%STRING2%"=="" SET /a COUNT=%COUNT%+1
aber jetzt beim tippen fällt mir auf was sein könnte - wenn die erste schleife nichts findet bleibt STRING1 leer und die 2. schleife schreibt in STRING1 (bis hirher is es genau so gewollt)
aber dann wird nicht weiter hochgezählt, da in der letzten zeile geprüft wird ob STRING2 leer ist.
aber wie kann ich das lösen, kann ja nicht schreiben
if not "%STRING%COUNT%%"==""
bitte um hilfe
und bei gelegenheit einige for-schleifen als beispiele mit variablen mit erklärung wär echt super
thx
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 42436
Url: https://administrator.de/forum/newbe-need-help-for-schleife-42436.html
Ausgedruckt am: 25.12.2024 um 08:12 Uhr
15 Kommentare
Neuester Kommentar
Hilfe zum Forbefehl findest du wenn du in der Eingabeaufforderung for /? eingibst.
zum ersten Problem:
Spalten vergleichen geht nicht, wenn dann Zeilen.
Wenn Du das willst dann:
Soll immer nur die erste Zeile von D1 mit der ersten zile von D2 verglichen werden? Oder ob die erste Zeile von D1 irgentwo in D2 vorkommt?
miniversum
zum ersten Problem:
Spalten vergleichen geht nicht, wenn dann Zeilen.
Wenn Du das willst dann:
Soll immer nur die erste Zeile von D1 mit der ersten zile von D2 verglichen werden? Oder ob die erste Zeile von D1 irgentwo in D2 vorkommt?
miniversum
Hallo WindowsUser1984!
Dein Problem 1 verstehe ich wie folgt:
Du hast zwei Textdateien, in denen jeweils in den einzelnen Zeilen mindestens 2 durch Leerzeichen und/oder Tabulatoren getrennte Werte stehen, wobei der erste dieser Werte als "Schlüssel" dient.
Als Ergebnis möchtest Du, dass alle Zeilen der ersten Datei, deren Schlüsselwert sich noch nicht in den Schlüsselwerten der zweiten Tabelle befindet, an die zweite Tabelle angehängt werden. Richtig?
Problem 2 ist für mich "problematischer", da die eigentliche Zielsetzung nicht zu erkennen ist. Vielleicht könntest Du mit einigen Beispielen (Zeilen der Eingabedatei und gewünschtes Ergebnis) den Sinn der Aktion deutlich machen!
Dein Problem 1 verstehe ich wie folgt:
Du hast zwei Textdateien, in denen jeweils in den einzelnen Zeilen mindestens 2 durch Leerzeichen und/oder Tabulatoren getrennte Werte stehen, wobei der erste dieser Werte als "Schlüssel" dient.
Als Ergebnis möchtest Du, dass alle Zeilen der ersten Datei, deren Schlüsselwert sich noch nicht in den Schlüsselwerten der zweiten Tabelle befindet, an die zweite Tabelle angehängt werden. Richtig?
Problem 2 ist für mich "problematischer", da die eigentliche Zielsetzung nicht zu erkennen ist. Vielleicht könntest Du mit einigen Beispielen (Zeilen der Eingabedatei und gewünschtes Ergebnis) den Sinn der Aktion deutlich machen!
Hallo WindowsUser1984!
Auf Verdacht ein Entwurf für Problem 1:
Alle Zeilen von TestDat.txt werden darauf hin untersucht, ob der erste Wert (bis zum ersten Leerzeichen/Tab) bereits in einer Zeile von VerglDat.txt als erster Wert vorkommt (Groß- / Kleinschreibung wird nicht unterschieden). Wenn dem nicht so ist, wird die ganze Zeile aus TestDat.txt (oder genauer, der erste Wert, eine Leerstelle und der Rest der Zeile) an VerglDat.txt angehängt. Hinweis: Falls das Trennzeichen in TestDat.txt ein Tab war, wird trotzdem als neues Trennzeichen eine Leerstelle verwendet.
Natürlich lässt sich das Ganze so ändern, dass die beiden Dateinamen als Argumente übergeben werden können - liest sich dann nur etwas schwerer als die obige Variante.
Für das Problem mit der Übernahme der "Originalzeile" (also ohne ev. verändertes Trennzeichen bzw mit enthaltenen Anführungszeichen) ist mir noch folgendes eingefallen:
Hier nehme ich die ganze Zeile in einer Variable mit und lasse das Herausfiltern des ersten Wertes durch die automatische Aufspaltung bei der Übergabe an :Vergl2 erledigen ...
Grüße
bastla
Auf Verdacht ein Entwurf für Problem 1:
@echo off
for /f "tokens=1*" %%i in (TestDat.txt) do call :Vergl %%i "%%j"
set neu=
goto :eof
:Vergl
set neu=1
for /f "tokens=1*" %%a in (VerglDat.txt) do call :Vergl2 %1 %%a
if %neu%==1 echo %1 %~2 >> VerglDat.txt
goto :eof
:Vergl2
if /i %1==%2 set neu=0
Alle Zeilen von TestDat.txt werden darauf hin untersucht, ob der erste Wert (bis zum ersten Leerzeichen/Tab) bereits in einer Zeile von VerglDat.txt als erster Wert vorkommt (Groß- / Kleinschreibung wird nicht unterschieden). Wenn dem nicht so ist, wird die ganze Zeile aus TestDat.txt (oder genauer, der erste Wert, eine Leerstelle und der Rest der Zeile) an VerglDat.txt angehängt. Hinweis: Falls das Trennzeichen in TestDat.txt ein Tab war, wird trotzdem als neues Trennzeichen eine Leerstelle verwendet.
Natürlich lässt sich das Ganze so ändern, dass die beiden Dateinamen als Argumente übergeben werden können - liest sich dann nur etwas schwerer als die obige Variante.
Für das Problem mit der Übernahme der "Originalzeile" (also ohne ev. verändertes Trennzeichen bzw mit enthaltenen Anführungszeichen) ist mir noch folgendes eingefallen:
for /f "delims=" %%i in (TestDat.txt) do set line=%%i & call :Vergl
set neu=
goto :eof
:Vergl
set neu=1
for /f "tokens=1*" %%a in (VerglDat.txt) do call :Vergl2 %%a %line%
if %neu%==1 echo %line% >> VerglDat.txt
goto :eof
:Vergl2
if /i %1==%2 set neu=0
Hier nehme ich die ganze Zeile in einer Variable mit und lasse das Herausfiltern des ersten Wertes durch die automatische Aufspaltung bei der Übergabe an :Vergl2 erledigen ...
Grüße
bastla
Und weil ich gerade dabei bin - eine Alternative zu obigem Ansatz:
Ich nehme an (ohne es getestet zu haben), dass diese Version bei größeren Dateien erhebliche Laufzeitvorteile bringen müsste.
bastla
[Edit] %%~j auf %%j reduziert [/Edit]
@echo off
for /f "tokens=1*" %%i in (TestDat.txt) do findstr /b /i %%i VerglDat.txt || echo %%i %%j >> VerglDat.txt
Ich nehme an (ohne es getestet zu haben), dass diese Version bei größeren Dateien erhebliche Laufzeitvorteile bringen müsste.
bastla
[Edit] %%~j auf %%j reduziert [/Edit]
Hallo WindowsUser1984!
An sich unterscheidet sich für mich die Situation (programmtechnisch) zwischen den Rechnern 1 bis 3 und dem Rechner 4 nicht wirklich - alle haben eine lokal gespeicherte Liste von Zielrechnern (in der Liste kommt - sinnvoller Weise - der eigene Rechner nicht vor, bei Rechner 4 sollte eben zusätzlich auch der Server nicht drinnen sein), an die dann per Batch kopiert wird.
Müssen die weiteren Parameter (bitte auch dazu Beispiele) wirklich in der gleichen Datei stehen?
Sinnvolle Überlegung - allerdings würde ich aber, wie oben angedeutet, die Rechnerliste getrennt von weiteren Einstellungen führen.
Grüße
bastla
Daten werden an otherPC(4) vorbereitet und dan den PC1 - PC3 korregiert/bearbeitet und auf die die anderen PCs und den server gesichert ... heufigkeit ca 10 - 25 mal täglich
Von dem otherPC(4) aus möchte ich aber nicht an den server senden.
also habe ich eine lokale Datei mit den netzwerkadressen der anderen PC die ich auslese.
z.B.:
Datei von PC2:
> PC1 = \\blabla1...
> PC3 = \\blabla3...
> server = \\AAAA...
Datei von otherPC
> PC1 = \\....
> PC2 = \\....
> PC3 = \\....
>server = \\....
Datei von PC2:
> PC1 = \\blabla1...
> PC3 = \\blabla3...
> server = \\AAAA...
Datei von otherPC
> PC1 = \\....
> PC2 = \\....
> PC3 = \\....
>
An sich unterscheidet sich für mich die Situation (programmtechnisch) zwischen den Rechnern 1 bis 3 und dem Rechner 4 nicht wirklich - alle haben eine lokal gespeicherte Liste von Zielrechnern (in der Liste kommt - sinnvoller Weise - der eigene Rechner nicht vor, bei Rechner 4 sollte eben zusätzlich auch der Server nicht drinnen sein), an die dann per Batch kopiert wird.
Da ich in dieser Datei ua weitere Parameter für andere Dateien habe kann ich auch nicht einfach die ersten 3 Zeilen auslesen da ich für meine anderen batches dann wiederum an dem Problem hänge.
Müssen die weiteren Parameter (bitte auch dazu Beispiele) wirklich in der gleichen Datei stehen?
nun ist die lösung gesucht zum auslesen dieser lokalen dateien mit adressen der pcs, so das ich von allen PCs nur eine funktionierende version brauche
Sinnvolle Überlegung - allerdings würde ich aber, wie oben angedeutet, die Rechnerliste getrennt von weiteren Einstellungen führen.
Grüße
bastla
Hallo WindowsUser1984!
Vielleicht ziehst Du das Ganze wie folgt auf:
Die Batchdatei würde dann nach Deiner Vorgabe so aussehen:
Aufruf daher von jedem Rechner (zB zum Kopieren von "QuellDat.txt" aus "D:\Zu Verteilen" auf alle Zielrechner):
Noch eine Frage: Werden eigentlich mehrere Dateien gleichzeitig kopiert (was /E vermuten ließe)? In diesem Fall wäre die Überprüfungsabfrage (für %~nx1) etwas problematisch ...
Grüße
bastla
Vielleicht ziehst Du das Ganze wie folgt auf:
Lokale Rechnerliste(n) mit zeilenweisem Eintrag der Zielrechner und -Pfade:
C:\Listen\Alle.txt und C:\Listen\AlleWS.txt (letztere ohne Server)
Beispiel für den Inhalt von Alle.txt auf PC2 (\\Rechnername\Freigabe\Unterverzeichnis[se]):
\\blabla1\Import\Neue
\\blabla3\Import3\Neu\Ganz Neu
\\AAAA\Eingang\Gesamt
Batch-Datei am Server: Verteil.cmd in Freigabe Batches
Die Batchdatei würde dann nach Deiner Vorgabe so aussehen:
@echo off
for /f "delims=" %%i in (%2) do Call :Kopiere %1 "%%i"
goto :eof
:Kopiere
if not exist %2 echo %2 nicht vorhanden oder Netzwerk nicht verbunden. & pause
xcopy %1 %2 /C /E /I 2>nul >nul
if not exist "%~2\%~nx1" echo Datei %~n1 konnte nicht kopiert werden. & echo.
Aufruf daher von jedem Rechner (zB zum Kopieren von "QuellDat.txt" aus "D:\Zu Verteilen" auf alle Zielrechner):
\\Server\Batches\Verteil.cmd "D:\Zu Verteilen\QuellDat.txt" C:\Listen\Alle.txt (oder AlleWS.txt)
Noch eine Frage: Werden eigentlich mehrere Dateien gleichzeitig kopiert (was /E vermuten ließe)? In diesem Fall wäre die Überprüfungsabfrage (für %~nx1) etwas problematisch ...
Grüße
bastla
Hallo WindowsUser1984!
So ist es - Ziel ist, die ganze Zeile aus der Rechnerliste zu lesen (erspart mir, in der Datei Alle.txt Anführungszeichen zu verwenden, diese wegzufiltern und wieder neu zu setzen)
Ja (nennt sich Unterprogrammtechnik)
Grüße
bastla
"delims=" in der hilfe steht, Zeichen das das std Trennzeichen(leer und tab) ersetzt da aber keines angegeben ist frage ich mich warum es überhaubt da steht? und nehme an wenn die tokens nicht vorkommen wird alles gelesen und als %1 weitergegeben?
So ist es - Ziel ist, die ganze Zeile aus der Rechnerliste zu lesen (erspart mir, in der Datei Alle.txt Anführungszeichen zu verwenden, diese wegzufiltern und wieder neu zu setzen)
call :kopiere %1 "%%i" (wuste nicht das goto nicht geht aber dafür call) sieht so aus als springst du aus der schleife und wieder zurück!
Ja (nennt sich Unterprogrammtechnik)
wie wird festgelegt wann in der for-schleife weitergemacht wird? funktioniert das auch mit einem befehl oder muss die Datei dort enden?
LetzteresNehme an das %1 "%%i" als %1 %2 weitergegeben werden!?
Wie beim Aufruf der Batchdatei selbst sind alle übergebenen Argumente durchnummeriert Bin mir nicht sicher aber goto :eof dient zum beenden des programmablaufes durch undefinierter Sprungmarke!?
Richtighätte natürlich alles blind übernehmen können aber denke wenn ichs mal verstehe dann belästige ich dich weniger ;-D
Find ich gut , betrachte Deine Fragen aber keineswegs als Belästigung, sondern eher als HerausforderungGrüße
bastla
Moin WindowsUser1984,
ich glaube (so wie ich den Thread mitgelesen habe), dass ihr an einer Stelle aneinander vorbeigeschrieben habt:
Mitnichten.
Die *.bat-Datei muss dort nicht enden.
In einer *.bat/*.cmd-Datei können auch mehrere "call :subBlock"-Aufrufe stehen.
Jeder dieser Blöcke sollte eigentlich mit einem "goto :eof" enden.
In diesem Kontext ("geCALLter Anweisungsblock") bedeutet "goto :eof" in etwa dasselbe wie in anderen Skript-Sprachen "RETURN" oder "END PROC"..also Ende der aufgerufenen Unterroutine.
Das "sollte eigentlich" eben heißt: Wenn ein Call-Anweisungsblock-Ende zufällig gleichzeitig auch das Ende der Batchdatei ist (so wie in bastla's Skizze), dann kann/darf das abschließende "goto :eof" entfallen.
Nicht entfallen dagegen darf das "goto :eof", das das Ende des "Haupt-Batches" angibt - das nach der FOR..IN..DO-Anweisung.
@WindowsUser1984
Bitte den Beitrag auf "Gelöst" setzen, wenn es für Dich auch hinreichend beantwortet ist. Danke.
@bastla
Es sollte nur eine Klarstellung einer IMHO missverständlichen Formulierung sein.
Habe sonst keinerlei Einwände gegen die Lösungsskizze.
Gruß
Biber
ich glaube (so wie ich den Thread mitgelesen habe), dass ihr an einer Stelle aneinander vorbeigeschrieben habt:
wie wird festgelegt wann in der for-schleife weitergemacht wird?
funktioniert das auch mit einem befehl oder muss die Datei dort enden?
funktioniert das auch mit einem befehl oder muss die Datei dort enden?
Letzteres.
Mitnichten.
Die *.bat-Datei muss dort nicht enden.
In einer *.bat/*.cmd-Datei können auch mehrere "call :subBlock"-Aufrufe stehen.
Jeder dieser Blöcke sollte eigentlich mit einem "goto :eof" enden.
In diesem Kontext ("geCALLter Anweisungsblock") bedeutet "goto :eof" in etwa dasselbe wie in anderen Skript-Sprachen "RETURN" oder "END PROC"..also Ende der aufgerufenen Unterroutine.
Das "sollte eigentlich" eben heißt: Wenn ein Call-Anweisungsblock-Ende zufällig gleichzeitig auch das Ende der Batchdatei ist (so wie in bastla's Skizze), dann kann/darf das abschließende "goto :eof" entfallen.
Nicht entfallen dagegen darf das "goto :eof", das das Ende des "Haupt-Batches" angibt - das nach der FOR..IN..DO-Anweisung.
@WindowsUser1984
Bitte den Beitrag auf "Gelöst" setzen, wenn es für Dich auch hinreichend beantwortet ist. Danke.
@bastla
Es sollte nur eine Klarstellung einer IMHO missverständlichen Formulierung sein.
Habe sonst keinerlei Einwände gegen die Lösungsskizze.
Gruß
Biber