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

Problem mit IF und FOR in der Batch

Frage Entwicklung Batch & Shell

Mitglied: 65452

65452 (Level 1)

22.06.2010 um 21:04 Uhr, 2567 Aufrufe, 11 Kommentare

Ich stehe gerade auf dem Schlauch bei einer IF-Abfrage innerhalb einer FOR-Schleife!

Hallo,

ich habe eine Textdatei in der Form:

01.
zeile1 
02.
zeile2 
03.
zeile3 
04.
zeile4 
05.
zeile5 
06.
zeile6
Diese Textdatei würde ich gerne in die Form

01.
zeile1;zeile2;zeile3; 
02.
zeile4;zeile5;zeile6;
bringen.

Da dies in Zukunft häufiger vorkommen wird, dachte ich: "Mach dir eine Batch, das wird nicht allzu wild sein..."
Gesagt, getan:

01.
set zaehler=1 
02.
 
03.
FOR /F %%i In (123.txt) Do ( 
04.
Set /p =%%i;<nul>>result.txt 
05.
SET /A zaehler=%zaehler%+1 
06.
	if %zaehler% == 4 ( 
07.
		ECHO.>>result.txt 
08.
	) else ( 
09.
		ECHO Zaehler zu klein 
10.
11.
 
12.
)
Soweit so gut, nur sieht das Ergebnis leider so aus:
01.
Zeile1;Zeile2;Zeile3;Zeile4;Zeile5;Zeile6;
Kann mir bitte kurz jemand erklären, was ich falsch mache?

Ray
Mitglied: Biber
22.06.2010 um 21:39 Uhr
Moin SL2MDS,

auch du kaufst deine Nicks offensichtlich nicht von der Stange...

Eine Skizze zum Weitertesten und Verfeinern könnte so aussehen:
01.
@echo off & setlocal EnableDelayedExpansion 
02.
::---zaehlerInFor.cmd-----Skizze, kein Produktiv-Batch --- 
03.
Set "outfile=result.txt" 
04.
:: Zum Testen reicht Ausgabe in Datei CON=Bildschirm 
05.
Set "outfile=Con" 
06.
set /a zaehler=0 
07.
set "oneLine=" 
08.
FOR /F %%i In (123.txt) Do ( 
09.
   Set "Oneline=!oneline!;%%i" 
10.
   SET /A zaehler=!zaehler!+1 
11.
	if !zaehler! == 4 ( 
12.
	        Set "zaehler=0"   
13.
		ECHO.!oneline:~1!>>%outfile% 
14.
		Set "oneLine=" 
15.
	) else ( 
16.
		ECHO [Debug] Zaehler ist !zaehler! OneLine ist "!Oneline!" ...weiter... 
17.
18.
)
und würde am CMD-Prompt folgenden Output liefern [führendes ">" ist mein Prompt; nicht mit eingeben]:
>for /L %i in (1,1,9) do @echo zeile%i >>123.txt 
>type 123.txt 
zeile1 
zeile2 
zeile3 
zeile4 
zeile5 
zeile6 
zeile7 
zeile8 
zeile9 
 
>zaehlerInFor.cmd 
[Debug] Zaehler ist 1 OneLine ist ";zeile1" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";zeile1;zeile2" ...weiter... 
[Debug] Zaehler ist 3 OneLine ist ";zeile1;zeile2;zeile3" ...weiter... 
zeile1;zeile2;zeile3;zeile4 
[Debug] Zaehler ist 1 OneLine ist ";zeile5" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";zeile5;zeile6" ...weiter... 
[Debug] Zaehler ist 3 OneLine ist ";zeile5;zeile6;zeile7" ...weiter... 
zeile5;zeile6;zeile7;zeile8 
[Debug] Zaehler ist 1 OneLine ist ";zeile9" ...weiter...
Erläuterung bzw. Strohhalme zum Weiterhangeln:
Für den CMD-Interpreter, der die Batch-Befehle abarbeitet, ist ein "FOR...In..DO( )" oder auch einer "IF ( ) ELSE ()" -Konstrukt immer EINE Zeile.
Auch wenn du sie optisch auseinanderziehst auf 2 DIN A4-Seiten.
In EINER zeile wird eine Variable %var% nur EINmal aufgelöst... wenn es losgeht mit der Ausführung.

Es sei denn, man/frau sagt an "Hey, mach mir verzögerte Variablenauflösung!" neudeutsch: "DelayedExpansion", Zeile 01".
Und nach der Ansage müssen die "verzögert aufzulösenden Variablen" als !var! statt %var% angesprochen werden.

Hilfe zu allen verwendeten Befehlen wie SetLocal, FOR, SET etc --> am CMD-prompt mit FOR/?, Set /? .....

[##Edit##]
Gerade gesehen, dass ich jeweil 4 "Zellen" zu einer neuen mache statt wie gefordert 3 Zeilen.
Nochmal:
>zaehlerInFor.cmd 
[Debug] Zaehler ist 1 OneLine ist ";zeile1" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";zeile1;zeile2" ...weiter... 
[Output] zeile1;zeile2;zeile3 
[Debug] Zaehler ist 1 OneLine ist ";zeile4" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";zeile4;zeile5" ...weiter... 
[Output] zeile4;zeile5;zeile6 
[Debug] Zaehler ist 1 OneLine ist ";zeile7" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";zeile7;zeile8" ...weiter... 
[Output] zeile7;zeile8;zeile9
... bei Änderung des Schnipsels auf:
01.
@echo off & setlocal EnableDelayedExpansion 
02.
Set "outfile=result.txt" 
03.
:: Zum Testen reicht Ausgabe in Datei CON=Bildschirm 
04.
Set "outfile=Con" 
05.
set /a zaehler=0 
06.
set "oneLine=" 
07.
FOR /F %%i In (123.txt) Do ( 
08.
   Set "Oneline=!oneline!;%%i" 
09.
   SET /A zaehler=!zaehler!+1 
10.
	if !zaehler! == 3 ( 
11.
	        Set "zaehler=0"   
12.
		ECHO.[Output] !oneline:~1!>>%outfile% 
13.
		Set "oneLine=" 
14.
	) else ( 
15.
		ECHO [Debug] Zaehler ist !zaehler! OneLine ist "!Oneline!" ...weiter... 
16.
))
[/##Edit##]


Grüße
Biber
Bitte warten ..
Mitglied: LotPings
23.06.2010 um 00:07 Uhr
Nachdem ich heute (nein gerade gestern)
eine Batch Split-x.cmd gepostet habe, hier eine Join-x.cmd die als Alternative zu Bibers Version auch Ausrufezeichen im Text verarbeiten kann.
01.
:: Join-X.cmd 
02.
@Echo off & Setlocal 
03.
Set InFile="123.txt" 
04.
Set Outfile=^>^>"123.new" 
05.
Type NUL %OutFile:~1% 
06.
Set X=3 
07.
Set "Line=" 2>Nul 
08.
For /F "tokens=1,* delims=[]" %%A in ( 
09.
  'find /N /V "#+#" ^< %InFile%' 
10.
    ) Do Call :ProcessLine %%A "%%B" 
11.
if defined Line %OutFile% Echo.%Line% 
12.
Goto :Eof 
13.
:ProcessLine 
14.
Set /A "Rest=%1 %% X " 
15.
Set Line=%~2;%Line% 
16.
If %Rest% EQU 0 ( 
17.
%OutFile% Echo.%Line% 
18.
Set "Line=" 
19.
)
Gruß
LotPings
Bitte warten ..
Mitglied: Biber
23.06.2010 um 08:06 Uhr
Moin LotPings,

sieht ja vielversprechend aus...
Aber die Ausgabe ist noch leicht unterschiedlich, wenn ich deinen Schnipsel über die o.b. 123.txt laufen lasse.

>Join-X.cmd 
 
(= 8:04:15  F:\schnipsel=) 
>type 123.new 
zeile3 ;zeile2 ;zeile1 ; 
zeile6 ;zeile5 ;zeile4 ; 
zeile9 ;zeile8 ;zeile7 ; 
 
(= 8:05:11  F:\schnipsel=) 
>zaehlerInFor.cmd|find /v "Debug" 
[Output] zeile1;zeile2;zeile3 
[Output] zeile4;zeile5;zeile6 
[Output] zeile7;zeile8;zeile9
Grüße
Biber
Bitte warten ..
Mitglied: LotPings
23.06.2010 um 09:54 Uhr
Moin Biber,

ich hab ja schonmal gesagt "Es ist schön das wir aufeinander aufpassen"

Der Fehler mit der Reihenfolge war von mir verschuldet, das mit dem Leerzeichen dazwischen liegt aber am Inhalt deiner Datei 123.txt.
Diese leicht geänderte Version mit integriertem Trim und zusätzlichem Echo auf den Bildschirm:
01.
:: Join-X.cmd 
02.
@Echo off & Setlocal 
03.
Set InFile="123.txt" 
04.
Set Outfile=^>^>"123.new" 
05.
Type NUL %OutFile:~1% 
06.
Set X=3 
07.
Set "Line=" 2>Nul 
08.
For /F "tokens=1,* delims=[]" %%A in ( 
09.
  'find /N /V "#+#" ^< %InFile%' 
10.
    ) Do Set /A "Rest=%%A %% X"&Call :ProcessLine %%B 
11.
if defined Line Echo %Line% & %OutFile% Echo.%Line% 
12.
Goto :Eof 
13.
:ProcessLine 
14.
Set Line=%Line%%*; 
15.
If %Rest% EQU 0 (Echo.%Line% 
16.
  %OutFile% Echo.%Line% 
17.
  Set "Line=" 
18.
)
Kommt auch mit dieser erschwerten 123.txt klar
zeile 1 
zeile 2 
zeile 3! 
zeile 4 
zeile 5 
zeile 6! 
zeile 7  
zeile 8  
zeile 9 ! 
zeile 10 
Was deine Version leider nicht tut, sie mag neben Ausrufe- keine Leerzeichen im Text und unterschlägt in der Ausgabe die Zeile 10.

Gruß
LotPings
Edit: Bei meiner Bildschirmausgabe hatte ich den Überhang bei nicht durch 3 teilbaren Zeilen auch vergessen, ist korrigiert.
Bitte warten ..
Mitglied: Biber
23.06.2010 um 12:09 Uhr
Moin LotPings,

du hast natürlich Recht mit dem überzähligen Blank in der Testdatei 123.txt.
Und auch damit, dass ich mit der Mimik über DelayedExpansion Ausrufungszeichen nicht richtig gut verarbeiten kann.

Die überzähligen (nicht durch 3 teilbaren) Zeilenreste allerdings hatte ich nicht vergessen, sondern wollte dem geschätzten TO auch noch etwas übrig lassen.

Ich würde (wahrscheinlich) auch diese Anforderung mit einem "Call: ProcessNext" statt alles in den FOR..In..DO-Klammern lösen.
Mein Ansatzpunkt hier im Thread war aber, die vorhandenen Codezeilen mindestens wiedererkennbar zu erhalten.

Also wäre eine Weniger-Buggy-Proof-of-Concept-Version diese hier:
01.
::---zaehlerMitDelayedExpansion.cmd 
02.
@echo off & setlocal EnableDelayedExpansion 
03.
Set "infile=%~dp0123.txt" && REM Bein Testen ist Infile=123.txt und wird ggf angelegt 
04.
 
05.
IF not exist "%infile%" (for /L %%i in (1,1,22) do (echo altezeile%%i)>>%infile%) 
06.
Set "outfile=result.txt" 
07.
:: Zum Testen reicht Ausgabe in Datei CON=Bildschirm 
08.
Set "outfile=Con" 
09.
set /a zaehler=0 
10.
set "oneLine=" 
11.
FOR /F "delims=" %%i In (%infile%) Do ( 
12.
   Set "Oneline=!oneline!;%%i" 
13.
   SET /A zaehler=!zaehler!+1 
14.
	if !zaehler! == 3 ( 
15.
	        Set "zaehler=0"   
16.
		ECHO.[Output] !oneline:~1!>>%outfile% 
17.
		Set "oneLine=" 
18.
	) else ( 
19.
		ECHO [Debug] Zaehler ist !zaehler! OneLine ist "!Oneline!" ...weiter... 
20.
)) 
21.
IF defined oneLine ECHO.[OutputRest] !oneline:~1!>>%outfile%
Änderungen:
  • Testfile 123.txt wird ggf. angelegt
  • eine "alteZeile" in der 123.txt kann nun auch Leerzeichen/mehrere Token enthalten
  • Ein vorhandener Rest der "altenZeilen", der insgesamt keine "ganze" neue Outputzeile ergibt wird angezeigt.
Output:
 
(=12:08:36  F:\schnipsel=) 
>zaehlerMitDelayedExpansion.cmd 
[Debug] Zaehler ist 1 OneLine ist ";altezeile1" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile1;altezeile2" ...weiter... 
[Output] altezeile1;altezeile2;altezeile3 
[Debug] Zaehler ist 1 OneLine ist ";altezeile4" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile4;altezeile5" ...weiter... 
[Output] altezeile4;altezeile5;altezeile6 
[Debug] Zaehler ist 1 OneLine ist ";altezeile7" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile7;altezeile8" ...weiter... 
[Output] altezeile7;altezeile8;altezeile9 
[Debug] Zaehler ist 1 OneLine ist ";altezeile10" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile10;altezeile11" ...weiter... 
[Output] altezeile10;altezeile11;altezeile12 
[Debug] Zaehler ist 1 OneLine ist ";altezeile13" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile13;altezeile14" ...weiter... 
[Output] altezeile13;altezeile14;altezeile15 
[Debug] Zaehler ist 1 OneLine ist ";altezeile16" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile16;altezeile17" ...weiter... 
[Output] altezeile16;altezeile17;altezeile18 
[Debug] Zaehler ist 1 OneLine ist ";altezeile19" ...weiter... 
[Debug] Zaehler ist 2 OneLine ist ";altezeile19;altezeile20" ...weiter... 
[Output] altezeile19;altezeile20;altezeile21 
[Debug] Zaehler ist 1 OneLine ist ";altezeile22" ...weiter... 
[OutputRest] altezeile22
Grüße
Biber
Bitte warten ..
Mitglied: LotPings
23.06.2010 um 12:32 Uhr
Na dann hat Ray ja einiges zum Studieren,
denn auch aus Fehlern anderer kann man lernen.

Gruß
LotPings

Uuups, ich sehe gerade Rays Vorgabe war auch ein Semikolon am Ende der Zeile....
Bitte warten ..
Mitglied: Biber
23.06.2010 um 16:26 Uhr
Moin Lordchen,

Zitat von LotPings:
Na dann hat Ray ja einiges zum Studieren,
denn auch aus Fehlern anderer kann man lernen.
Kann er nicht aus seinen eigenen lernen, so wie wir es auch jeden gatesverdammten Tag wieder tun müssen?

Uuups, ich sehe gerade Rays Vorgabe war auch ein Semikolon am Ende der Zeile....
Tja, mit meiner Strategie hab ich es da jetzt leichter.
Ich schneide doch ohnehin ein überzähliges ";" vom Beginn der Variable %OneLine% ab...
Wenn ich das ohnehin schon mal in der Hand habe, kann ich es doch am Ende der Variable wieder ankleben, oder?

Viele nennen mich auch "Biber, den Recycler"

Grüße
Biber
Bitte warten ..
Mitglied: LotPings
23.06.2010 um 16:35 Uhr
Zitat von Biber:
Kann er nicht aus seinen eigenen lernen, so wie wir es auch jeden gatesverdammten Tag wieder tun müssen?
Stimmt, statt Kreuzworträtsel oder Sudokus zu lösen mache ich lieber Batche mit Fehlern und lerne daraus.
Wenn ich das ohnehin schon mal in der Hand habe, kann ich es doch am Ende der Variable wieder ankleben, oder?
Nunja, eigentlich müsste deine Zeile 12 das semikolon nur am Ende anhängen statt dazwischen,
dann kann in Zeile 16+21 statt !oneline:~1! einfach nur !oneline! stehen.

Viele nennen mich auch "Biber, den Recycler"
Wäre ja auch blöd wenn wir das Rad jedesmal neu erfinden würden

Gruß
LotPings
Bitte warten ..
Mitglied: Biber
25.06.2010 um 17:30 Uhr
Moin SL2MDS,

können wir denn noch auf dein Feedback hoffen, bevor die deutsche Nationalmannschaft wieder den Rückflug antritt?

Grüße
Biber
Bitte warten ..
Mitglied: 65452
25.06.2010 um 17:43 Uhr
mmmhhh,

eigentlich hatte ich bereits direkt nach euren tollen Ausführungen ein Feedback hiergelassen...

Muss mir wohl ein Fehler unterlaufen sein.

Also hier das Feedback:

Ich habe dank eurer tollen Beispiele nun so einiges mehr verstanden, als ich mir hätte erhoffen können.
Somit konnte ich zusammen mit ein paar anderen Skripten und Tools nun endlich eine (fast) automatische Pflege unseres DHCP-Servers realisieren.
Ich finde es toll, wie ihr mir hier weitergeholfen habt und ziehe respektvoll meinen Hut vor euren Batch-Kenntnissen!


Ich wünsche euch beiden ein schönes Wochenende und hoffentlich einen freudigen Sonntag Nachmittag

Ray

P.S.: Nicks von der Stange sind doch langweilig...
Bitte warten ..
Mitglied: Biber
25.06.2010 um 19:02 Uhr
Moin SL2MDS,

Zitat von 65452:
mmmhhh,

...
Ich habe dank eurer tollen Beispiele nun so einiges mehr verstanden, als ich mir hätte erhoffen können.
Somit konnte ich zusammen mit ein paar anderen Skripten und Tools nun endlich eine (fast) automatische Pflege unseres DHCP-Servers
realisieren.
Ich finde es toll, wie ihr mir hier weitergeholfen habt und ziehe respektvoll meinen Hut vor euren Batch-Kenntnissen!
Danke schön. Das geht einem ja runter wie in Bad im Golf von Mexiko.

Ich wünsche euch beiden ein schönes Wochenende und hoffentlich einen freudigen Sonntag Nachmittag
Wünsche dir auch ein schönes Wochenende
Biber

P.S.: Nicks von der Stange sind doch langweilig...
Stimmt, und diese Billgimitate aus Rudis Resterampe oder aus dem TeDi haben meist nur 6 kryptische Ziffern und Grossbuchstaben...
Bitte warten ..
Neuester Wissensbeitrag
Ähnliche Inhalte
Batch & Shell
gelöst Grosses Variablen Problem ( Batch) (30)

Frage von clragon zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Problem bei einer For Schleife (2)

Frage von Juergen42 zum Thema Batch & Shell ...

Batch & Shell
gelöst Windows 7: Problem mit CP in Batch (3)

Frage von Maik87 zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Userverwaltung
Ausgeschiedene Mitarbeiter im Unternehmen - was tun mit den AD Konten? (32)

Frage von patz223 zum Thema Windows Userverwaltung ...

LAN, WAN, Wireless
FritzBox, zwei Server, verschiedene Netze (21)

Frage von DavidGl zum Thema LAN, WAN, Wireless ...

Viren und Trojaner
Aufgepasst: Neue Ransomware Goldeneye verbreitet sich rasant (20)

Link von Penny.Cilin zum Thema Viren und Trojaner ...

Windows Netzwerk
Windows 10 RDP geht nicht (18)

Frage von Fiasko zum Thema Windows Netzwerk ...