Top-Themen

Aktuelle Themen (A bis Z)

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 Batch - mit Variablen rechnen oder inkrementieren?

Mitglied: Jansen

Jansen (Level 1) - Jetzt verbinden

06.11.2005, aktualisiert 02.03.2016, 30203 Aufrufe, 7 Kommentare

Hallo!

Aus einer Textdatei nach folgendem Muster
01.
Wert: 10 
02.
blabla bleh strunz 
03.
Wert: 13 
04.
blubber blub göbel dum 
05.
Wert: 26
möchte ich die Summe der Zahlenwerte ermitteln. Mein Versuch sieht so aus

01.
@echo off 
02.
@set /a sum=0 
03.
@for /F "tokens=1,2" %%a in (c:\tmp.log) do ( 
04.
....@if "%%a"=="Wert:" ( 
05.
........@if NOT "%%b"=="0" ( 
06.
............@echo ZwWert=%%b 
07.
............@set /a sum=%sum%+%%b 
08.
............@echo ZwSum=%sum% 
09.
........) 
10.
....) 
11.
12.
@echo EndSum=%sum%
Links die erhoffte Ausgabe, recht die tatsächliche.
01.
ZwWert=10............ZwWert=10 
02.
ZwSum=10.............ZwSum=0 
03.
ZwWert=13............ZwWert=13 
04.
ZwSum=23.............ZwSum=0 
05.
ZwWert=26............ZwWert=26 
06.
ZwSum=49.............ZwSum=0 
07.
EndSum=49............EndSum=26
Wer kann mir sagen, wo es hier hakt und hat vor allem eine, gern auch alternative, Lösung?
Danke für alle Tips!

PS.
Zielsystem ist Win2K/XP, die betreffende Datei ist das Log von ntbackup, das auf "Ausgelassen:" und "Unterschiedlich:" geprüft werden soll. Perl, VBS etc. kommen aus "administrativen Gründen" leider nicht in Betracht.

PPS.
Den Thread Rechnen mit Variablen unter Batch habe ich gesehen und bin auch dem Link von Biber dort gefolgt, weitergebracht hat mich das leider nicht.
Mitglied: nullplan001
06.11.2005, aktualisiert 02.03.2016
Zunächst einmal kannst du die ganzen @ außer dem vor "echo off" löschen. Schon wird die Angelegenheit übersichtlicher. Und dann war da noch die Befehlserweiterung für WINNT. Lies dir mal bei Gelegenheit CMD /? durch.
Ich habe den Fehler aber schon ausgemacht: in der Schleife musst du den Befehl
01.
<tt>@set /a sum=%sum%+%%b</tt> in <tt>set /a sum=!sum!+%%b</tt>umwandeln
Und zwar deshalb: %sum% hat einen Wert. Dieser wird erst nach der Schleife aktualisiert. !sum! hat den Wert von %sum%, wird aber gleich in der Schleife aktualisiert. Wieso das so ist, fragst du besser Microsoft.
Bitte warten ..
Mitglied: Jansen
06.11.2005 um 12:35 Uhr
Hallo, danke für die Hilfe.

Lies dir mal bei Gelegenheit CMD /? durch.
Jo, hab ich schon, verstehe allerdings nicht genau, worauf du hinauswillst.

<tt>@set /a sum=%sum%+%%b</tt>
in <tt>set /a sum=!sum!+%%b</tt>
umwandeln.

Das produziert leider eine "Fehlender Operator"-Ausgabe.

Gruss,
Jansen
Bitte warten ..
Mitglied: Biber
06.11.2005, aktualisiert 02.03.2016
Moin Jansen,

Wieso das so ist, fragst du besser Microsoft.
...Biber fragen geht schneller..

Der Denkfehler ist folgender: Auch wenn Du die Anweisungen in Deiner FOR..IN..DO-Schleife noch so schön formatierst und in mehrere Zeilen auseinanderziehst - der CMD-Interpreter sieht und zieht sie als eine Zeile an.
Der liest sie zur Ausführungszeit en bloc ein und löst alle darin enthaltenen Variablen einmalig auf. Alle außer den FOR-Zählvariablen, die werden in jedem Schleifendurchlauf neu befüllt.
Du kannst dieses Verhalten beeinflussen/ändern über den Befehl
"setlocal EnableDelayedExpansion" .. verzögerte Variablen-Auflösung. Steht irgendwo in der Hilfe (SET/? oder CALL /?).

[Edit]
Wenn EnableDelayedExpansion nicht gesetzt ist, bekommst Du bei Verwendung der !var!-Syntax ein Problem:
>>Das produziert leider eine "Fehlender Operator"-Ausgabe.
[/Edit]

Oder aber.. ohne generelle DelayedExpansion geht es über das callen einer (Pseudo-)Subroutine.
Weil ich nicht so gut im Erklären bin, zeig ich das mal in einem Batchbeispiel.
01.
::-------snipp Summarize.bat 
02.
@echo off & setlocal 
03.
goto skipProsa 
04.
Die nächste Findstr-Zeile ist natürlich nur bei mir beim Testen sinnvoll. 
05.
Unten nach dem "goto :eof" stehen Deine Beispielzeilen (wie in der tmp.log). 
06.
Ich schreibe alle Zeilen, die mit "Wert:" beginnen, irgendwohin. 
07.
Bei Dir könnte dort stehen findstr /b "Wert:" c:\tmp.log>%NurWerte% 
08.
:SkipProsa 
09.
Set "NurWerte=%temp%\NurZeilenMitWertBeginnend.txt" 
10.
findstr /b "Wert:" Summarize.bat>%NurWerte% 
11.
Echo Die Werte: 
12.
Type %NurWerte% 
13.
Echo ----- 
14.
Call :Variante1 
15.
Call :Variante2 
16.
Call :Variante3 
17.
goto :eof 
18.
-----Ende des Haupt-Batches 
19.
 
20.
:Variante1 
21.
Echo Variante1) sum wird in EINER FOR..IN..DO..Zeile addiert 
22.
set /a sum=0  
23.
for /F "tokens=1,2" %%a in (%NurWerte%) do (      
24.
   if "%%a"=="Wert:" (  
25.
     if NOT "%%b"=="0" (  
26.
        set /a sum=%sum%+%%b  
27.
        echo ZwSum=%sum% ZwWert=%%b  
28.
        ) ) )  
29.
echo EndSum=%sum% 
30.
Goto :eof 
31.
----Ende :Variante1 
32.
---- 
33.
:Variante2 
34.
Echo. 
35.
Echo Variante2) sum wird in einem call:-Block addiert 
36.
set /a sum=0  
37.
for /F "tokens=1,2" %%a in (%NurWerte%) do call :Sum2 %%a %%b 
38.
echo EndSum=%sum% 
39.
goto :eof 
40.
----Ende :Variante2... ruft den Block ":sum2" 
41.
---- 
42.
:sum2 
43.
   if "%1"=="Wert:" (  
44.
     if NOT "%2"=="0" (  
45.
        set /a sum=%sum%+%2  
46.
        echo ZwSum=%sum% ZwWert=%2   
47.
        ) ) )  
48.
Goto :eof 
49.
----Ende :Sum2-"Subroutine" 
50.
------- 
51.
:Variante3 
52.
Echo. 
53.
Echo Variante3) ...etwas schlankere Version von Variante2 
54.
set /a sum=0  
55.
for /F "tokens=2" %%a in (%NurWerte%) do call :Sum3 %%a 
56.
echo EndSum=%sum% 
57.
goto :eof 
58.
----Ende :Variante3... ruft den Block ":sum3" 
59.
---- 
60.
:sum3 
61.
set /a sum+=%1  
62.
echo ZwSum=%sum% ZwWert=%1   
63.
Goto :eof 
64.
----Ende :Sum3-"Subroutine" 
65.
 
66.
Wert: 10  
67.
blabla bleh strunz  
68.
Wert: 0  
69.
Sülz di bülz  
70.
Wert: 13  
71.
blubber blub göbel dum  
72.
Wert: 26 
73.
-------snapp Summarize.bat
Der Output dieses Schnipsels:
01.
Summarize.bat 
02.
Die Werte: 
03.
Wert: 10 
04.
Wert: 0 
05.
Wert: 13 
06.
Wert: 26 
07.
----- 
08.
Variante1) sum wird in EINER FOR..IN..DO..Zeile addiert 
09.
ZwSum=0 ZwWert=10 
10.
ZwSum=0 ZwWert=13 
11.
ZwSum=0 ZwWert=26 
12.
EndSum=26 
13.
 
14.
Variante2) sum wird in einem call:-Block addiert 
15.
ZwSum=0 ZwWert=10 
16.
ZwSum=10 ZwWert=13 
17.
ZwSum=23 ZwWert=26 
18.
EndSum=49 
19.
 
20.
Variante3) ...etwas schlankere Version von Variante2 
21.
ZwSum=10 ZwWert=10 
22.
ZwSum=10 ZwWert=0 
23.
ZwSum=23 ZwWert=13 
24.
ZwSum=49 ZwWert=26 
25.
EndSum=49
Wenn das Deiner Meinung nach verständlich genug ist, hänge ich das nachher um als Tutorial.

Grüße
Biber
Bitte warten ..
Mitglied: Jansen
06.11.2005 um 15:26 Uhr
Danke!

Das Setzen von EnableDelayedExpansion funktioniert, und diese Variante werde ich auch verwenden (oder spricht etwas dagegen?).

Aber danke auch für die Alternativen, da habe ich wieder mehr gelernt als ursprünglich erhofft.
Bitte warten ..
Mitglied: Biber
06.11.2005, aktualisiert 02.03.2016
Moin Jansen,
ich habe auch in meiner CMD-"Workbench" immer das "EnableDelayedExpansion" gesetzt. Geht ja auch per Registry oder per AutoRun-Batch.
Kann aber seine Tücken haben, da ja nun alles zwischen zwei Ausrufungszeichen als Variable gnadenlos aufgelöst wird.
Dafür habe ich in meinem Workshop Batch for Runaways - Part II - Ein bisschen Handwerkszeug ein Beispiel, wo das in die Grütze geht. Wenn man/frau diesen Fall im Hinterkopf hat, ist es kein Problem.

Grüße
Frank / der Biber aus Bremen
Bitte warten ..
Mitglied: Jansen
06.11.2005 um 22:12 Uhr
Hmm ja, da werde ich die Auswertung wohl lieber per externem Batch erledigen, anstatt EDE direkt in das meterlange Backup-Script einzubauen.
Nochmals Danke für dein geduldiges Erklären!

Gruss,
Jansen
Bitte warten ..
Mitglied: Biber
07.11.2005, aktualisiert 02.03.2016
Na ja, Jansen,
ausreden wollte ich es Dir ja auch nicht.. nur die Tücken des Objekts aufzeigen.

In Deinem Fall kannst Du natürlich auch irgendwo in Deinem meterlangen Backup-Skript
(soll ich Dir das mal ein bisschen zusammendampfen? *gg)
noch einen kleinen 3-Zeilen Call-Block namens "getSumme" einbauen... ["set /a sum=0" muss vorher erfolgen]
01.
.. 
02.
:getSumme 
03.
setlocal EnableDelayedExpansion & set "NurWerte=c:\tmp.log" 
04.
for /F "tokens=2" %%a in (%NurWerte%) do set /a sum=!sum!+%%a 
05.
EndLocal & goto :eof 
06.
...
...hat ja schon einen gewissen Charme und würde ich wohl auch so machen.
Dann hast Du das "EnableDelayedExpansion" nur in diesem kleinen Block (durch "EndLocal" wieder auf vorherigen Stand gesetzt).

Andererseits .. ohne das DelayedExpansion-Feature hättest Du in Deinem Code eine Batch-Zeile mehr..was soll der Geiz?
Selbst meine Oneliner belegen auf manchen Festplatten 16.384 Bytes, obwohl keine Hundert Zeichen drin stehen.
Kannst also ruhig ein, zwei Zeilen mehr reinschreiben - kostet das Gleiche.

Stressarmen Wochenanfang
Biber
Bitte warten ..
Ähnliche Inhalte
Batch & Shell

Rechnen mit Variablen - Batch Programmierung

gelöst Frage von LH.AppsBatch & Shell7 Kommentare

Bei folgendem Code gibt er immer mehrere Ergebnisse oder "ECHO ist ausgeschaltet (OFF)." aus: Optimierungsvorschläge? PS: Für die Variable ...

Batch & Shell

Batch - Variablen

gelöst Frage von Marlon1Batch & Shell2 Kommentare

Hallo, Ich habe eine Frage zu Variablen. Und zwar ob es irgendwie geht das Batch mit ein IF Befehl ...

Batch & Shell

Batch-Variable rechnet immer weiter

Frage von ZwergkaninchenBatch & Shell4 Kommentare

Hallo, Leute! Ich wollte mir ein kleines Idle-Game in Batch schreiben, aber ich komm nicht weiter. Hier ist ein ...

Batch & Shell

Batch: Variable einen Wert zuweisen

gelöst Frage von veniplexBatch & Shell7 Kommentare

Hallo zusammen! Ich bin gerade am verzweifeln Ich habe in Batch 2 Variablen: Wenn ich mir von diesen den ...

Neue Wissensbeiträge
Windows 10

USB Maus und Tastatur versagen Dienst unter Windows 10

Erfahrungsbericht von hardykopff vor 2 TagenWindows 105 Kommentare

Da steht man ziemlich dumm da, wenn der PC sich wegen fehlender USB Tastatur und Maus nicht bedienen lässt. ...

Administrator.de Feedback
Update der Seite: Alles zentriert
Information von Frank vor 2 TagenAdministrator.de Feedback18 Kommentare

Hallo User, die größte Änderung von Release 5.8 ist das Zentrieren der Webseite (auf großen Bildschirmen) und ein "Welcome"-Teaser ...

Humor (lol)

WhatsApp-Nachrichten endlich auch per Bluetooth versendbar

Information von BassFishFox vor 3 TagenHumor (lol)5 Kommentare

Genau darauf habe ich gewartet! ;-) Der beliebte Messaging-Dienst WhatsApp erhält eine praktische neue Funktion: Ab dem nächsten Update ...

Google Android

Googles "Android Enterprise Recommended" für Unternehmen

Information von kgborn vor 3 TagenGoogle Android3 Kommentare

Hier eine Information, die für Administratoren und Verantwortliche in Unternehmen, die für die Beschaffung und das Rollout von Android-Geräten ...

Heiß diskutierte Inhalte
Router & Routing
Router auf Orginal Firmware zurück flashen mit Tftpd
Frage von ILeonardRouter & Routing21 Kommentare

Hallo, Ich habe zwei Router, einmal TP-Link 841n v11 und TP-Link 940N v5. Ich wollte fragen, ob jemand mir ...

Router & Routing
WRT keine Verbindung zum Web Interface
gelöst Frage von ILeonardRouter & Routing18 Kommentare

Hallo, Ich habe einen TP-Link WR841n mit wrt geflasht, das Problem ist ich kann mich mit 192.168.1.1 nicht verbinden. ...

Windows Server
Standortvernetzung zu einem Strato VServer (Windows)
Frage von matzefratze81Windows Server10 Kommentare

Moin, ich komme aus einem Enterprise-Umfeld und habe den Fehler gemacht, dass ich mich auf ein kleines Unternehmen eingelassen ...

TK-Netze & Geräte
Telefonie zweier Fritzboxen mit je eigenem DSL Anschluss verbinden
Frage von hannsgmaulwurfTK-Netze & Geräte10 Kommentare

Hallo zusammen, ich habe hier einen Haushalt mit zwei Anschlüssen. Einmal ISDN, einmal DSL. An jedem Anschluss hängt eine ...