Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit
GELÖST

Per Batch Zeilenweise aus einer Datei lesen - bei jedem Aufruf wird die nächste Zeile verwendet

Frage Entwicklung Batch & Shell

Mitglied: blacksun

blacksun (Level 1) - Jetzt verbinden

11.12.2007, aktualisiert 16.10.2012, 7745 Aufrufe, 17 Kommentare

und wenn Ende erreicht, soll wieder bei der ersten zeile begonnen werden

Hallo,

ich bräuchte mal wieder eure Hilfe bei der Erstellung einer Batch.

Und zwar geht es um folgendes.
Ich habe eine Datei, die pro Zeile einen Wert enthält.

z.B.

Hans
Peter
Gerda
...
Uwe



Ich möchte nun den jeweiligen Wert (also eine Zeile) auslesen und in einer Variablen verwenden.
Das könnte man ja mit

FOR %%f IN (datei.txt) DO echo %%f

welches hier Auslesen einzlner Zeilen aus einem TXT File mittels Batch beschrieben ist, bewerkstelligen.

Allerdings möchte ich nicht die einzelnen Werte am Stück auslesen.
Ich möchte, dass beim ersten Aufruf der Batch der Wert "Hans" ausgelesen und in eine Variable geschrieben wird. Beim zweiten Aufruf möchte ich den Wert "Peter" auslesen, usw.

Hinzu soll noch die Möglichkeit kommen, dass wenn man bei dem letzten Wert ist (in diesem Beispiel "Uwe"), dann soll die Batch beim nächsten Aufruf wieder beim ersten Wert "Hans" beginnen.
Es wäre schön, wenn man nicht irgendwo definieren muss, wieviele Zeilen die Datei hat, sondern wenn bei Erreichen des Endes automatisch wieder bei der 1. Zeile begonnen wird.


Wiegesagt wer hat hier eine Idee für mich, wie ich das hinbekommen kann.


Viele Grüße
Martin
Mitglied: 58502
11.12.2007 um 23:55 Uhr
Ohne externe Definition, sei es über die Registry, eine Datei oder das Systemenvironment geht das nicht, was du vorhast. Für das Setzen einer nichtflüchtigen Variablen benötigst du setx.exe aus den XP-Support-Tools.
Hellsehen kann auch das fortschrittlichste Betriebssystem (noch) nicht.
Bitte warten ..
Mitglied: blacksun
12.12.2007 um 11:48 Uhr
Hallo Siebenstein,

das ist klar, dass ich den verwendeten Wert in eine Variable schreiben muss.
Ich schreibe den Wert vor dem Beenden einfach in eine Datei und lese diesen beim nächsten Aufruf wieder von dort aus.

Das Problem ist aber, wie ich dann beim nächsten Aufruf nach dem Wert suche und dann die nächste Zeile als neuen Wert nehme.
Und die Sache mit EOF ist auch noch da. Sprich wenn die letzte Zeile erreicht wurde, soll wieder bei Zeile 1 gegonnen werden.

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
12.12.2007 um 11:54 Uhr
Du musst die Anzahl der bereits ausgelesenen Zeilen ermitteln, den Wert in eine Variable oder Datei schreiben. Anhand dieser Variablen kannst du dann mit SKIP die gelesenen Zeilen übergehen. Wenn du alle geSKIPPED hast, ist die Variable doch leer, dann beginnst du halt von vorn.

Beenden/Abbrechen kannst du den Spaß mit goto :EOF
Bitte warten ..
Mitglied: blacksun
12.12.2007 um 16:54 Uhr
Hättest Du mir ein Beispiel, wie das aussehen könnte.

Also das mit einem Wert in eine Datei schreiben und diesen Wert wieder aus der Datei zu lesen, das bekomm ich noch hin.

Aber wie Suche ich beim nächsten Aufruf mit diesem SKIP?
Geht das mit einem FOR ....?

Und kann ich mit dem EOF aus dem FOR-Befehl wirklich feststellen, wann das Listenende erreicht wurde und dann wieder bei Zeile 1 anfangen???

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
12.12.2007 um 17:06 Uhr
Wie skip funktioniert, steht in der Hilfe zu FOR, damit werden einfach n Zeilen übersprungen. Mit goto :eof beendest du nach skip und dem nachfolgen Lesen der nächsten Zeile (wenn eine da ist) den Ablauf. Wenn keine mehr da ist, dürfte die variable leer sein.

Ein fertiges Beispiel kannst du von mir nicht bekommen, nur Anregungen.
Nach meiner festen Überzeugung lernt man nur so den Umgang mit Batch-Scripten, und nur so bleibt auch was hängen.
Bitte warten ..
Mitglied: blacksun
12.12.2007 um 17:18 Uhr
also gut,

ich werd mich wenn es mir reicht heute abend mal intensiv mit dem FOR-Befehl beschäftigen.

das EOF gehört doch auch zum FOR-Befehl.

Und Du meinst wirklich, dass das, was ich wie beschrieben vor habe, so mit FOR möchlich ist? Brauch ich da nicht noch was anderes?

Nicht dass ich an der ganz falschen Stelle Suche.


Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
12.12.2007 um 17:20 Uhr
EOF ist das Dateiende der Batchdatei, das hat mit FOR wenig bis nichts zu tun.

Hier gibt es jede Menge Beispiele im Unterforum, etwas, aus dem du Teile entnehmen kannst, die auch erläutert sind, ist sicher dabei.
Bitte warten ..
Mitglied: blacksun
12.12.2007 um 23:46 Uhr
Hallo siebenstein,

also ich hab mir jetzt mal folgendes zusammengebastelt:

[code]
set skipVar=0
set rows=0
set /p skipVar=<skipCounter


FOR /F %%a IN (datei.txt) DO @set /a rows=rows + 1

IF /I %rows%-%skipVar% EQU 0 (set skipVar=0)


FOR /F "skip=%skipVar%" %%i IN (datei.txt) DO (@echo %i )

set /a skipVar=skipVar + 1
echo %skipVar% > skipCounter
[/code]

Nur das hilft mir jetzt nicht wirklich weiter, da jetzt zwar immer eine Zeile weniger, dafür aber jeweils immer der gesamte Rest an Zeilen ausgegeben wird.

Bsp.:
Inhalt datei.txt:
[code]
aaa
bbb
ccc
ddd
[/code]

Lasse ich obigen Code darüber laufen, erhalte ich beim ersten Aufruf folgendes:
aaa
bbb
ccc
ddd


Beim zweiten Durchlauf wird mittels SKIP die erste Zeile weggelassen:
bbb
ccc
ddd

usw.

ABER:
Ich brauche nicht den gesamten Rest, sondern nur die jeweils erste Zeile in einer Variablen.
Also beim ersten Durchlauf brauche ich z.B. aaa, beim zweiten Durchlauf soll die Variable den Wert bbb, und beim dritten Lauf ccc annehmen.

Hier komme ich jetzt nicht weiter.
Ich habe mir nun überlegt, ob ich nicht dynamisch Variablen anlegen lasse und lasse jeden noch aus der Datei ausgelesenen Wert in eine dynamische variable schreiben.
Ich ersetze dabei die oben FOR-Schleife oben durch diese Variante:

[code]
set counter=0

FOR /F "skip=%skipVar%" %%i IN (datei.txt) DO
(@set counter=counter+1
@set Wert%counter%=%%i
)
[/code]

Dann habe ich bei der jeweils ersten Zeile eines Durchlaufes in der Variablen "Wert1" der richtigen Wert stehen.
Sprich beim ersten durchlauf sollte das aaa sein, beim zweiten ist die erste zeile bbb, was dann auch in "Wert1" stehen sollte.

Allerdings funktioniert die FOR-Schleife so bei mir nicht.
Kannst Du mir sagen, wo der Fehler liegt? Ich kann doch hoffentlich zwei Befehle in "DO" ausführen lassen.
Oder vielleicht hast Du mir einen anderen Vorschlag.

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
13.12.2007 um 00:12 Uhr
Als erst mal musst du die Rows so speichern, dass sie nach dem Beenden auch noch zur Verfügung stehen, dazu solltest du setx.com (Support-Tools) benutzen. Die normalen Variablen sind nämlich beim Schließen des Konsolenfensters weg.

01.
if "%rows%=="" setx rows 0 
02.
set rows1=%rows% 
03.
set irgendwas= 
04.
 
05.
FOR /F "skip=%rows1%" %%i IN (datei.txt) DO  call :tuwas %%i 
06.
goto :eof 
07.
 
08.
:tuwas 
09.
rem den ausgelesenen Namen sichern 
10.
if "%1"=="" set rows=0 & setx rows 0 & goto :eof 
11.
 
12.
set irgendwas=%1 
13.
set /a rows1=+1 
14.
setx rows %rows1%
2 %% für Schleifenvariablen innerhalb der Batch, wenn du das direkt testest, darf die Schleifenvariable nur 1 % enthalten.

Nicht geprüft, ausprobieren musst du selbst.
Bitte warten ..
Mitglied: blacksun
13.12.2007 um 01:28 Uhr
Hallo Siebenstein,

das ist ein guter Tip mit dem

DO call :tuwas

In die Sprungmarke tuwas kann ich dann mehrere Befehle schreiben.

Und dass man auch Sprungmarken Parameter übergeben kann und man dann dort auf diese mit %1 zugreifen kann, war mir neu.

Für's erste hab ich nur noch eine Frage, die sich vielleicht böde anhört:

Mit dem DO call :tuwas

springst Du ja zu der Sprungmarke tuwas. Gibt es eigentlich eine Chance, dass man der Sprungmarke mitteilt, wann das Ende der Sprungmarke erreicht ist.

Selbst wenn ich darunter noch eine Sprungmarke :tuwasanderes habe, dann rauscht die FOR-Schleife bei Ihren durchgängen auch dort hindurch.
Weil eigentlich soll ja bei

01.
set irgendwas=%1 
02.
set /a rows1=+1 
03.
setx rows %rows1%
Schluss sein, und alles was darunter kommt soll nicht pro Schleifendurchgang abgearbeitet werden.

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
13.12.2007 um 02:27 Uhr
Ich will erst mal ein paar kleine Fehler beseitigen, das fertige Script bekommst du nicht, nur noch Tipps. So, wie der Code da steht, funktioniert er nicht

Beenden kannst du, wenn du am Ende des Calls, also als letzte Zeile exit eingibts.

Bei den Zeilen mit setx muss hinten noch ein -m ran, rows mit 0 geht nicht, dafür muss "" eingesetzt werden und wenn rows ="" ist, funktioniert die FOR-Schleife mit dem skip-Befehl nicht. Dann gutes Gelingen und fröhliche Bastelns. Kleiner Tipp noch: Du musst 2 bzw. 3 weitere Sprungmarken verwenden.

01.
@echo off & setlocal 
02.
if not "%rows%=="" set rows1=%rows% 
03.
set irgendwas= 
04.
 
05.
FOR /F "skip=%rows1%" %%i IN (datei.txt) DO  call :tuwas %%i 
06.
goto :eof 
07.
 
08.
:tuwas 
09.
rem den ausgelesenen Namen sichern 
10.
if "%1"=="" set rows= & setx rows "" -m & goto :eof 
11.
 
12.
set irgendwas=%1 
13.
set /a rows1=+1 
14.
setx rows %rows1% -m 
15.
echo %irgendwas% 
16.
echo %rows1% 
17.
pause 
18.
exit
Bitte warten ..
Mitglied: blacksun
13.12.2007 um 20:25 Uhr
Hallo siebenstein,

so langsam wird das ja auch bei mir.

Mit dem Ende hab ich mich wohl falsch ausgedrückt. Ich meine damit nicht das Beenden der Batch (über exit), sondern das Ende der Sprungmarke.

Nehmen wir mal den Beispielcode:

[code]
FOR /F %%i IN (datei.txt) DO call :tuwas %%i


:tuwas
set irgendwas=%1
set /a rows1=+1
setx rows %rows1% -m
echo %irgendwas%
echo %rows1%


:tuwasanderes
echo "123"

[/code]


Wenn ich das so aufrufe, dann führt die For-Schleife für jeden Durchlauf ja die Sprungmarke :tuwas aus, führt aber auch alles darunter, also die Sprungmarke :tuwasanderes aus.
Sprich pro Schleifendurchlauf wird auch
echo "123" ausgeführt.

In :tuwasanderes steht aber Code, der erst nach der dem Durchlauf der Schleife ausgeführt werden soll. Schreibe ich aber nach echo %rows1% ein exit , dann wird nicht die Schleife beendet, sondern die ganze batch.

Ich bin also auf der Such nach einer Möglichkeit, dass nach echo %rows1% ein Schleifendurchlauf am Ende ist und der nächste Lauf der For-Schleife beginnen soll.

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
13.12.2007 um 20:42 Uhr
Ein call eine Unterroutine ist das Gleiche, als wenn man eine externe Batch aufruft. Du musst die Unterroutine mit goto :eof beenden; die externe Bätch würde sich selbst beenden, wenn der Ablauf beendet ist. D. h. nach :tuwas und vor :tuwasanderes gehört ein goto :eof.

Ich will mal nicht so sein, sonst quälst du dich noch in Wochen.

Hier der funktionierende Code:
01.
@echo off & setlocal 
02.
set rows1= 
03.
set irgendwas= 
04.
 
05.
if not "%rows%"=="" goto :nichtleer 
06.
 
07.
:start 
08.
set parm="delims=" 
09.
set rows1=0 
10.
 
11.
goto :weiter 
12.
FOR /F %parm% %%i IN (datei.txt) DO  call :tuwas %%i 
13.
goto :eof 
14.
 
15.
:nichtleer 
16.
set rows1=%rows% 
17.
set parm="skip=%rows%" 
18.
 
19.
:weiter 
20.
FOR /F %parm% %%i IN (datei.txt) DO  call :tuwas %%i 
21.
goto :start 
22.
 
23.
:tuwas 
24.
rem den ausgelesenen Namen sichern 
25.
if "%1"=="" set rows= & setx rows ""-m & goto :eof 
26.
 
27.
set irgendwas=%1 
28.
set /a rows1=rows1+1 
29.
setx rows %rows1% -m 
30.
echo %irgendwas% 
31.
rem echo %rows1% 
32.
pause 
33.
exit

Die Batch-Datei muss immer separat aufgerufen werden, nicht aus einem geöffneten Konsolenfenster, sonst funktioniert sie nicht. Wenn du das nicht willst, musst du die Variable ROWS in eine Datei oder in die Registry schreiben und damit verarbeiten.
Bitte warten ..
Mitglied: blacksun
13.12.2007 um 21:30 Uhr
genau das wäre die alternative gewesen, das mit der seperaten Batch-Datei. Allerdings mag ich da überhaupt nicht, wenn jede funktion in einer seperaten Datei steht, die dann wieder mit call aufgerufen wird. Außerdem stehen in einer mit call aufgerufenen 2. Batch die Variablen nicht zur Verfügung.
Von daher ist die Idee von Dir mit der Sprungmarke eine feine Sache.

jetzt versteh ich auch das mit :eof

for /f %%i (datei.txt) do call :tuwas %%i
startet die for-Schleife und ruft die Sprungmarke auf, so als würde man eine zweite Batch aufrufen. Und das Beenden der zweiten untergeordneten Batch passiert bei der Sprungmarke über goto :eof

Und was dann nach dem Ende de For-Schleife passieren soll, dafür schreibe ich dann goto :tuwasanderes

[code]
for /f %%i (datei.txt) do call :tuwas %%i
goto :tuwasanderes

:tuwas
befehle pro Schleifendurchgang
goto :eof

:tuwasanderes
befehle, die nach dem vollständigen Ende der Schleife ausgeführt werden sollen.
[/code]


Ich bastel bei meiner Idee mal noch ein wenig weiter und vergleiche dann mal, ob ich auf diesselbe Batch komme wie du.
Jetzt hast Du mich ganz angestachelt. Jetzt will ich das Problem mal ausfechten

Viele Grüße
Martin
Bitte warten ..
Mitglied: blacksun
13.12.2007 um 21:51 Uhr
Hallo siebenstein,

bin nun auch mit meiner Idee fertig:

[code]
set skipVar=0
set /p skipVar=<skipCounter
set rows=0
set Vornamen=nix
set counter=0

FOR /F %%a IN (datei.txt) DO @set /a rows=rows + 1

IF /I %rows%==%skipVar% (set skipVar=0)


IF %skipVar%==0 (
FOR /F %%i IN (datei.txt) DO call :tuwas %%i
) ELSE (
FOR /F "skip=%skipVar%" %%i IN (datei.txt) DO call :tuwas %%i
)
goto :machweiter


:tuwas
set Vornamen=%1
set /a counter=counter+1
set Wert%counter%=%Vornamen%
goto :eof


:machweiter
set /a skipVar=skipVar + 1
echo %skipVar% > skipCounter

REM Hier wird das eingetragen, was mit der pro Aufruf
REM ausgelesenen Zeile gemacht werden soll

echo %Wert1% >> Ergebnis.txt

[/code]

Was meinst Du, was könnte man hier verbessern?

Viele Grüße
Martin
Bitte warten ..
Mitglied: 58502
13.12.2007 um 21:57 Uhr
Ganz gegen meine Einstellung habe ich dir doch eine fertige Lösung präsentiert, dein Problemchen wäre damit gelöst.
Ohne dir zu nahe treten zu wollen, aber ich bin kein Ersatz für einen Programmierkurs. Lass mich da bitte raus. Du wirst das schon schaffen: Üben, üben, üben.
Bitte warten ..
Mitglied: blacksun
13.12.2007 um 22:21 Uhr
Hallo siebenstein,

so hab ich das auch nicht gemeint.
Nach langem Durchkämpfen hab ich nun doch ein mit Deiner Hilfe ein Batch-Skriptchen hinbekommen, das mein Problem löst.
Von daher hat Du nicht gegen Deine Einstellung verstoßen.

Auf jeden Fall erstmal ganz herzliches Dankeschön für Deine Hilfe.

Viele Grüße
Martin
Bitte warten ..
Neuester Wissensbeitrag
Microsoft

Lizenzwiederverkauf und seine Tücken

(1)

Erfahrungsbericht von DerWoWusste zum Thema Microsoft ...

Ähnliche Inhalte
Batch & Shell
gelöst Ordner per Batch verschieben, Datei kopieren (2)

Frage von Shape.Shifter zum Thema Batch & Shell ...

Batch & Shell
gelöst BATCH ini Datei Datei auslesen (2)

Frage von Juergen42 zum Thema Batch & Shell ...

Batch & Shell
Batch: Word Datei kopieren und umbennen (9)

Frage von ExcelNoob177 zum Thema Batch & Shell ...

Batch & Shell
Neuere Datei per Batch ausfinding machen (2)

Frage von chattie zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Server
Outlook Verbindungsversuch mit Exchange (15)

Frage von xbast1x zum Thema Windows Server ...

Microsoft Office
Keine Updates für Office 2016 (13)

Frage von Motte990 zum Thema Microsoft Office ...

Grafikkarten & Monitore
Tonprobleme bei Fernseher mit angeschlossenem Laptop über HDMI (11)

Frage von Y3shix zum Thema Grafikkarten & Monitore ...