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

Text-Datei mittels Batchprogramm konvertieren - Zeilen löschen, ungültige Einträge löschen, variable Länge in fixe Länge, Duplikate löschen

Frage Entwicklung Batch & Shell

Mitglied: UHU-stic

UHU-stic (Level 1) - Jetzt verbinden

13.01.2013, aktualisiert 14.01.2013, 2665 Aufrufe, 8 Kommentare

Hallo zusammen,
erst mal vielen Dank für diese Webseite - ich habe hier viel gelernt und auch meine Anforderung gelöst bekommen!
Nun stehe ich vor dem Problem, dass die Batch die ich erstellt habe, zwar funktioniert, jedoch alles andere als performant ist und entsprechend lange zur Verarbeitung braucht.
Leider muss ich auf ein Batchprogramm zurückgreifen - somit keine gutgemeinten Ratschläge bzgl. VBS o.ä.

Beschreibung der Aufgabe

Ich habe die Herausforderung eine Datei von Format A nach Format B zu wandeln und den ein oder anderen "Fehler" aus dieser zu entfernen.
Konkret bedeute dies:

  1. Die Datei beginnt mit fünf Zeilen - die nicht weiter benötigt werden und gelöscht (bzw. nicht in die Ergebnissdatei geschrieben) werden können
  2. Die Datei hat sowohl " als auch Leerstellen die sich bei der weiteren Verarbeitung als "störend" herausstellten, somit habe ich diese " eliminert und die Leerstellen gegen ~ (Tilde) ersetzt - dies ist jedoch nur ein Zwischenschritt, auf den ich gerne verzichten würde
  3. Die Datei hat nach den ersten zwei Schritten fehlerhafte Einträge, die ich gerne loswerden würde. Fehlerhafte Einträge können sein
    1. Eine Nummer (Jobnummer) in der Datei ist nicht gleich dem Dateinamen (die Jobnummer sind die ersten 9 Stellen der ReferenceNumber)
    2. Der weitere Teil der ReferenceNumber (Stücknummer = letzte 7 Stellen der ReferenceNumber) in der Datei wurde fehlerhaft übergeben und an der letzten Stelle fehlt die Zahl
    3. Die ReferenceNumber wurde gar nicht übergeben
      • All diese drei fehlerhaften Einträge sollen in eine Errorlog geschrieben werden
  4. Die nun "bereinigte" Datei soll von der variablen Länge in eine fixe Länge gebracht werden, nicht alles was in der Ursprungsdatei steht, wird in der Zieldatei gebraucht. Außerdem werden Einträge teilweise verändert bzw. die Positionen neu gemischt.
  5. Die Zieldatei muss sortiert ausgegeben werden
  6. Die Zieldatei darf keine doppelten Einträge haben. Dieser Teil ist im Moment der, der mir am meisten weh tut - er dauert einfach ewig.
    1. Mit Batchdatei aus einer .txt alle doppelten Zeilen (Duplikate) komplett löschen
      • Variante 1 von bastla vom 27.05.2009 um 21:29:07 habe ich verstanden und so nachgebaut.
      • Variante 4 von LotPings vom 28.05.2009 um 11:01:26 Uhr hingegen kapiere ich überhaupt nicht. Dort scheint aber ein Sort direkt mit in die Abfrage eingebaut zu sein - evtl. macht es dies effizienter?
        • Ich hatte hier die Idee, dass man die hier momentan implementierte FINDSTR Abfrage irgendwie so abändert, dass diese, aufgrund der Tatsache, dass die Datei ja bereits sortiert ist, immer nur die n nächsten Zeilen prüft und wenn in LineNo+=1 keine Übereinstimmung gefunden wird, die Prüfung abgebrochen wird. Nach meinem Verständnis geht der FINDSTR Befehl immer die komplette Datei durch, bei meiner momentanen Testdatei mit ca. 7500 Einträgen dauert das doch recht lange
  7. So, zum Schluss will ich noch den Statuswert von X nach Y umsetzen - hätte ich vermutlich schon weiter oben mitmachen können... Somit bitte nicht meckern - die von mir erstellte Batch ist meine erste etwas größere, die Anfängerfehler seien mir also bitte verziehen.

Hier mal ein Schnipsel aus der Datei - damit geht es natürlich flott und alles ist fein - wie gesagt, meine Testdatei ist leider 7500 Einträge groß, die in der Realität können auch mal 60000 Einträge haben...

Testdatei mit allen relevanten "Fehlern"

123456789.txt
01.
Firstline to be deleted 
02.
Second line to be deleted 
03.
Third line to be deleted 
04.
Forth line to be deleted 
05.
"RecordTime" "ReferenceNumber" "NotNeeded1" "NotNeeded2" "NotNeeded3" "NotNeeded4" "NotNeeded5" "NotNeeded6" "NotNeeded7" "NotNeeded8" "NotNeeded9" "NotNeeded10" "Status" "NotNeeded11" "NotNeeded12" "Cnt01" "Cnt02" "NotNeeded12" "NotNeeded13" "NotNeeded14" "NotNeeded15" "NotNeeded16" "NotNeeded17" 
06.
"2012.12.12.15.54.04" "" 1 1 1 1 1 0 1 0 0 0 2 0 8 2 0 0 0 0 0 0 0 
07.
"2012.12.12.15.54.07" "123456789000000" 1 1 0 1 1 600 1 1 0 1 1 0 24 5 0 0 0 0 0 0 0 
08.
"2012.12.12.15.54.08" "1234567890000000" 1 1 0 0 1 200 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 
09.
"2012.12.12.15.54.09" "1234567890000000" 1 1 0 0 1 200 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 
10.
"2012.12.12.15.54.10" "1234567890000000" 1 1 0 0 1 200 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 
11.
"2012.12.12.16.29.03" "1234567890000066" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
12.
"2012.12.12.16.29.05" "1234567890000067" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
13.
"2012.12.12.16.32.38" "123456789000006" 1 1 0 1 1 500 1 1 0 1 1 0 144 3 1 0 0 0 0 0 0 
14.
"2012.12.12.16.32.50" "1234567890000069" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
15.
"2012.12.12.16.33.44" "1234567890000070" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
16.
"2012.12.12.16.35.45" "1234567890000107" 1 1 0 1 1 400 1 1 0 1 1 0 8 2 1 0 0 0 0 0 0 
17.
"2012.12.12.16.37.30" "1234567890000108" 1 0 0 1 1 400 1 1 0 1 1 0 10 2 1 0 0 0 0 0 0 
18.
"2012.12.12.16.37.31" "1234567890000109" 0 1 0 1 1 400 1 1 0 1 1 0 9 2 1 0 0 0 0 0 0 
19.
"2012.12.12.16.40.46" "1234567890000111" 1 1 0 1 1 400 1 1 0 1 0 0 136 1 2 0 0 0 0 0 0 
20.
"2012.12.12.16.42.27" "1234567890000111" 1 1 1 1 1 0 1 0 0 0 2 0 136 1 0 0 0 0 0 0 0 
21.
"2012.12.12.16.43.32" "1234567890000114" 1 1 0 1 1 600 1 1 0 1 1 0 152 2 3 0 0 0 0 0 0 
22.
"2012.12.12.16.43.33" "1234567890000115" 1 1 0 1 1 500 1 1 0 1 1 0 8 3 1 0 0 0 0 0 0 
23.
"2012.12.12.16.43.34" "1234567890000116" 1 1 0 1 1 400 1 1 0 1 1 0 8 2 1 0 0 0 0 0 0 
24.
"2012.12.12.16.43.35" "1234567890000117" 1 1 0 0 1 500 1 0 0 0 0 0 0 3 1 0 0 0 0 0 0 
25.
"2012.12.12.16.51.47" "1234567890000155" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
26.
"2012.12.12.16.57.28" "1234567890000156" 1 1 0 0 1 500 1 0 0 0 0 0 0 3 1 0 0 0 0 0 0 
27.
"2012.12.12.16.57.29" "1234567890000157" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
28.
"2012.12.12.16.57.30" "1234567890000158" 0 0 0 1 1 200 1 1 0 1 1 0 27 1 0 0 0 0 0 0 0 
29.
"2012.12.12.16.57.31" "1234567890000158" 0 1 0 1 1 300 1 1 0 1 1 0 17 1 1 0 0 0 0 0 0 
30.
"2012.12.12.16.57.32" "1234567890000159" 1 1 0 1 1 500 1 1 0 1 1 0 16 3 1 0 0 0 0 0 0 
31.
"2012.12.12.16.57.34" "1234567890000160" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
32.
"2012.12.12.16.57.35" "1234567890000161" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
33.
"2012.12.12.16.57.36" "1234567890000162" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
34.
"2012.12.12.18.48.41" "1234567890000798" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
35.
"2012.12.12.18.53.59" "1234567890000798" 1 1 1 1 1 0 1 0 0 0 2 0 136 2 0 0 0 0 0 0 0 
36.
"2012.12.12.18.55.05" "100000800220000" 1 1 0 1 1 500 1 1 0 1 1 0 152 3 1 0 0 0 0 0 0 
37.
"2012.12.12.18.55.10" "1234567890000802" 1 1 0 1 1 800 1 1 0 1 1 0 136 2 5 0 0 0 0 0 0 
38.
"2012.12.12.18.55.10" "1234567890000803" 1 1 0 0 1 500 1 0 0 0 0 0 0 3 1 0 0 0 0 0 0 
39.
"2012.12.12.18.55.10" "1234567890000804" 1 1 0 0 1 400 1 0 0 0 0 0 0 2 1 0 0 0 0 0 0 
40.
"2012.12.12.19.19.24" "1234567890002889" 1 1 0 1 1 400 1 1 0 1 1 0 136 3 0 0 0 0 0 0 0 
41.
"2012.12.12.19.19.26" "1234567890002890" 1 0 0 1 1 400 1 1 0 1 1 0 10 2 1 0 0 0 0 0 0 
42.
"2012.12.12.19.40.36" "" 1 1 1 1 1 0 1 0 0 0 2 0 8 0 0 0 0 0 0 0 0 
43.
"2012.12.12.19.40.42" "" 1 0 1 1 1 0 1 0 0 0 2 0 26 1 0 0 0 0 0 0 0 
44.
"2012.12.12.19.40.51" "123456789000289" 0 1 1 1 1 0 1 0 0 0 2 0 153 3 2 0 0 0 0 0 0 
45.
"2012.12.12.19.40.52" "1234567890002896" 1 1 0 1 1 400 1 1 0 1 1 0 128 3 0 0 0 0 0 0 0 
46.
"2012.12.12.19.40.54" "1234567890002897" 1 1 0 1 1 300 1 1 0 1 1 0 128 2 0 0 0 0 0 0 0 
47.
"2012.12.12.19.35.50" "1234567890005231" 1 1 0 1 1 800 1 1 0 1 1 0 152 2 5 0 0 0 0 0 0


Meine Batchdatei

Hier dann also mein Code - wie in meinem Vorwort geschrieben, 99% von dem ist von dieser Seite abgeleitet, somit wundert Euch nicht, dass man die Handschrift des Einen oder Anderen von Euch in dem Skrpit wiederfindet:

01.
  
02.
@echo off  
03.
setlocal enabledelayedexpansion  
04.
 
05.
set "Datei=C:\Test\%1"  
06.
set "JobID=%1" 
07.
set "t=%temp%\Temp.tmp"  
08.
if exist "%t%" del "%t%"  
09.
 
10.
::----Hier werden die Schritte 1. (fünf Zeilen üerbspringen) und 2. (" rausschmeißen, Leerzeichen gegen Tilde ersetzen) durchgeführt 
11.
set "Von= " 
12.
set "Nach=~" 
13.
FOR /F "delims=" %%i in ("%Datei%") do (  
14.
       FOR /F "usebackq skip=5 delims=" %%j in ("%%~i") do set "line=%%j" & set "line=!line:%Von%=%Nach%!" & echo !line:^"=!>>"%t%" 
15.
16.
move "%t%" "%Datei%" 
17.
 
18.
::----Hier wird Schritt 3.1. (Jobnummer ungleich Dateiname rausschmeißen) durchgeführt 
19.
::----Es wird eine Error Datei mit den fehlerhaften Einträgen erzeugt  
20.
for /f "usebackq delims=" %%i in ('%Datei%') do set "JobID=%%~ni"  
21.
for /f "tokens=1-4 delims=:," %%a in ("%time%") do set "Stunde=%%a" & set "Minute=%%b" & set "Sekunde=%%c" & set "Milisekunde=%%d"  
22.
for /f "usebackq delims=" %%i in ("%Datei%") do call :ProcessLine0 "%%i"  
23.
move "%t%" "%Datei%" 
24.
 
25.
::----Hier wird Schritt 3.2. (Stücknummer zu kurz, durch das ersetzen in 2. steht hier nun immer eine ~) durchgeführt 
26.
(die letzte Stelle fehlt) 
27.
set "CodeA=~"  
28.
for /f "usebackq delims=" %%i in ("%Datei%") do call :ProcessLine1 "%%i"  
29.
move "%t%" "%Datei%" 
30.
 
31.
::----Hier wird Schritt 3.3. (Stücknummer ungültig - es steht immer eine 0000000 da) durchgeführt 
32.
set "CodeB=0000000"  
33.
for /f "usebackq delims=" %%i in ("%Datei%") do call :ProcessLine2 "%%i"  
34.
move "%t%" "%Datei%" 
35.
 
36.
::----Hier wird Schritt 4. (Variable Länge wird auf fixe Länge geändert, Felder werden neu angeordnet) durchgeführt 
37.
set "Leer16=                     " 
38.
set "Leer20=                         " 
39.
set "Leer3=000" 
40.
 
41.
for /f "tokens=1-23 delims=~" %%a in (C:\Test\%1) do (   
42.
    set "RecordTime=%%a%Leer20%"  
43.
    set "ReferenceNumber=%%b%Leer16%"  
44.
    set "Status=%Leer3%%%m" 
45.
    set "Cnt01=%Leer3%%%p" 
46.
    set "Cnt02=%Leer3%%%q" 
47.
    set /a "Cnt1=%%p" 
48.
    set /a "Cnt2=%%q" 
49.
    set /a "CntTotal=CntAim1+CntAim2" 
50.
echo !ReferenceNumber:~0,16! !Status:~-2! !RecordTime:~0,4!!RecordTime:~5,2!!RecordTime:~8,2!!RecordTime:~11,2!!RecordTime:~14,2!!RecordTime:~17,2! !Cnt01:~-3! !Cnt02:~-3! !CntTotal!>>"%t%" 
51.
)   
52.
move "%t%" "%Datei%" 
53.
 
54.
for /f "tokens=1-6 delims= " %%a in (C:\Test\%1) do (   
55.
    set "ReferenceNumber=%%a" 
56.
    set "Status=%%b" 
57.
    set "RecordTime=%%c" 
58.
    set "Cnt01=%%d" 
59.
    set "Cnt02=%%e" 
60.
    set "CntTotal=%Leer3%%%f" 
61.
echo !ReferenceNumber! !Status! !RecordTime! !Cnt01! !Cnt02! !CntTotal:~-3! 98>>"%t%" 
62.
)   
63.
move "%t%" "%Datei%" 
64.
 
65.
::----Hier wird Schritt 5. (die Datei wird aufsteigend sortiert) durchgeführt 
66.
sort "%Datei%">"%t%" 
67.
move "%t%" "%Datei%" 
68.
 
69.
::----Hier wird Schritt 6. (die doppelten Einträge werden aus der Datei gelöscht) durchgeführt 
70.
set "Duplikate=%temp%\Duplikate.txt" 
71.
set /a LineNo=0  
72.
copy nul "%Duplikate%">nul 
73.
for /f "usebackq delims=" %%i in ("%Datei%") do set "Zeile=%%i" & call :ProcessLine3 
74.
move "%t%" "%Datei%" 
75.
del "%Duplikate%" 
76.
 
77.
::----Hier wird Schritt 7. (Statuswert wird verändert) durchgeführt - gute werden von 00 auf 10 gesetzt alle anderen (schlechten) auf 20 
78.
set "Status=00"  
79.
for /f "usebackq delims=" %%i in ("%Datei%") do ( 
80.
    set "Z=%%i" & call :ProcessLine4  
81.
82.
move "%t%" "%Datei%" 
83.
 
84.
 
85.
::----Unterhalb dieser Zeile werden die Processlines abgearbeitet - das goto :eof ist somit für alle darüber liegenden Abfragen  
86.
goto :eof  
87.
 
88.
:ProcessLine0  
89.
set "Line=%~1"  
90.
if "%Line:~20,9%"=="%JobID%" echo !Line!>>"%t%" 
91.
if not "%Line:~20,9%"=="%JobID%" echo !Line!>>"%JobID%"_%date%_!Stunde!!Minute!!Sekunde!.err 
92.
goto :eof 
93.
 
94.
:ProcessLine1  
95.
set "Line=%~1"  
96.
if not "%Line:~35,1%"=="%CodeA%" echo !Line!>>"%t%" 
97.
goto :eof 
98.
 
99.
:ProcessLine2  
100.
set "Line=%~1"  
101.
if not "%Line:~29,7%"=="%CodeB%" echo !Line!>>"%t%" 
102.
goto :eof 
103.
 
104.
:ProcessLine3 
105.
set /a LineNo+=1  
106.
rem echo Prüfe Zeile %LineNo% ...  
107.
findstr /b /c:"%Zeile:~0,16%%D%" "%t%">nul && >>"%Duplikate%" echo %Zeile% || >>"%t%" echo %Zeile% 
108.
goto :eof 
109.
 
110.
:ProcessLine4  
111.
set "Line=%Z:~0,50%%D%" 
112.
set "ReferenceNumber=%Z:~0,16%%D%" 
113.
set "HintererTeil=%Z:~20,30%%D%" 
114.
if not "%Line:~17,2%"=="%Status%" echo !ReferenceNumber! 20 !HintererTeil!>>"%t%" 
115.
if "%Line:~17,2%"=="%Status%" echo !ReferenceNumber! 10 !HintererTeil!>>"%t%" 
116.
goto :eof 
117.
 
So, nun habe ich nicht mehr viel hinzuzufügen. Außer, dass Euch mein Dank sicher ist!
Eine letzte Anmerkung / Fragen hätte ich jedoch noch:
Bei den Tests bin ich einmal von einer drehenden Platte auf eine SSD umgezogen, da ich vermutete, dass die schlechte Performance primär in den Schreib- und Lesevorgängen begründet ist. Eine echte Verbesserung konnte ich jedoch nicht feststellen. Somit noch die Frage, wie kann ich meine Batchdatei evtl. mit mehr CPU Power schneller machen?
Ein Aufruf von start /high namederbatch.bat 123456789.txt hat leider nichts gebracht.

Mitglied: Friemler
13.01.2013, aktualisiert 14.01.2013
Hallo UHU-stic,

ich habe einige Optimierungen eingebaut und ein paar Protokoll-Ausgaben eingefügt. Hier ist das Ergebnis:
01.
@echo off & setlocal enabledelayedexpansion 
02.
 
03.
set "Datei=%~1" 
04.
set "JobID=%~n1" 
05.
set "t=%TEMP%\Temp.tmp" 
06.
 
07.
 
08.
::----Hier werden die Schritte 1. (fünf Zeilen üerbspringen) und 2. (" rausschmeißen, Leerzeichen gegen Tilde ersetzen) durchgeführt 
09.
echo Schritte 1 u. 2 
10.
 
11.
set "Von= " 
12.
set "Nach=~" 
13.
 
14.
(for /f "usebackq skip=5 tokens=* delims=" %%j in ("%Datei%") do ( 
15.
   set "line=%%j" 
16.
   set "line=!line:%Von%=%Nach%!" 
17.
   echo !line:^"=! 
18.
)) >"%t%" 
19.
 
20.
move "%t%" "%Datei%" > NUL 
21.
 
22.
 
23.
::----Hier wird Schritt 3.1. (Jobnummer ungleich Dateiname rausschmeißen) durchgeführt 
24.
::----Es wird eine Error Datei mit den fehlerhaften Einträgen erzeugt 
25.
echo Schritt 3.1 
26.
 
27.
for /f "tokens=1-4 delims=:," %%a in ("%TIME%") do ( 
28.
  set "Stunde=%%a" 
29.
  set "Minute=%%b" 
30.
  set "Sekunde=%%c" 
31.
  set "Milisekunde=%%d" 
32.
33.
 
34.
(for /f "usebackq tokens=* delims=" %%i in ("%Datei%") do ( 
35.
   set "Line=%%i" 
36.
   if "!Line:~20,9!" equ "%JobID%" ( 
37.
     echo !Line! 
38.
   ) else ( 
39.
     1>&2 echo !Line! 
40.
41.
)) 1>"%t%" 2>"%JobID%_%DATE%_%Stunde%%Minute%%Sekunde%.err" 
42.
 
43.
move "%t%" "%Datei%" > NUL 
44.
 
45.
 
46.
::----Hier wird Schritt 3.2. (Stücknummer zu kurz, durch das ersetzen in 2. steht hier nun immer eine ~) durchgeführt 
47.
::(die letzte Stelle fehlt) 
48.
echo Schritt 3.2 
49.
 
50.
set "CodeA=~" 
51.
 
52.
(for /f "usebackq tokens=* delims=" %%i in ("%Datei%") do ( 
53.
   set "Line=%%i" 
54.
   if "!Line:~35,1!" neq "%CodeA%" echo !Line! 
55.
)) >"%t%" 
56.
 
57.
move "%t%" "%Datei%" > NUL 
58.
 
59.
 
60.
::----Hier wird Schritt 3.3. (Stücknummer ungültig - es steht immer eine 0000000 da) durchgeführt 
61.
echo Schritt 3.3 
62.
 
63.
set "CodeB=0000000" 
64.
 
65.
(for /f "usebackq tokens=* delims=" %%i in ("%Datei%") do ( 
66.
   set "Line=%%i" 
67.
   if "!Line:~29,7!" neq "%CodeB%" echo !Line! 
68.
)) >"%t%" 
69.
 
70.
move "%t%" "%Datei%" > NUL 
71.
 
72.
 
73.
::----Hier wird Schritt 4. (Variable Länge wird auf fixe Länge geändert, Felder werden neu angeordnet) durchgeführt 
74.
echo Schritt 4 
75.
 
76.
set "Leer16=                     " 
77.
set "Leer20=                         " 
78.
set "Leer3=000" 
79.
 
80.
(for /f "usebackq tokens=1,2,13,16,17 delims=~" %%a in ("%Datei%") do ( 
81.
   set "RecordTime=%%a%Leer20%" 
82.
   set "ReferenceNumber=%%b%Leer16%" 
83.
   set "Status=%Leer3%%%c" 
84.
   set "Cnt01=%Leer3%%%d" 
85.
   set "Cnt02=%Leer3%%%e" 
86.
   set /a Cnt1=%%d 
87.
   set /a Cnt2=%%e 
88.
   set /a CntTotal=CntAim1+CntAim2 
89.
   echo !ReferenceNumber:~0,16! !Status:~-2! !RecordTime:~0,4!!RecordTime:~5,2!!RecordTime:~8,2!!RecordTime:~11,2!!RecordTime:~14,2!!RecordTime:~17,2! !Cnt01:~-3! !Cnt02:~-3! !CntTotal! 
90.
)) >"%t%" 
91.
 
92.
move "%t%" "%Datei%" > NUL 
93.
 
94.
(for /f "usebackq tokens=1-6" %%a in ("%Datei%") do ( 
95.
   set "CntTotal=%Leer3%%%f" 
96.
   echo %%a %%b %%c %%d %%e !CntTotal:~-3! 98 
97.
)) >"%t%" 
98.
 
99.
move "%t%" "%Datei%" > NUL 
100.
 
101.
 
102.
::----Hier wird Schritt 5. (die Datei wird aufsteigend sortiert) durchgeführt 
103.
echo Schritt 5 
104.
 
105.
sort "%Datei%" > "%t%" 
106.
move "%t%" "%Datei%" > NUL 
107.
 
108.
 
109.
::----Hier wird Schritt 6. (die doppelten Einträge werden aus der Datei gelöscht) durchgeführt 
110.
echo Schritt 6 
111.
 
112.
set "Duplikate=%TEMP%\Duplikate.txt" 
113.
set /a Cnt=0 
114.
set "Line=" 
115.
set "PrevLine=" 
116.
 
117.
type NUL > "%Duplikate%" 
118.
 
119.
(for /f "usebackq tokens=* delims=" %%a in ("%Datei%") do ( 
120.
   set "Line=%%a" 
121.
    
122.
   if /i "!Line:~0,16!" equ "!PrevLine:~0,16!" ( 
123.
     echo %%a 
124.
     set /a Cnt+=1 
125.
126.
   set "PrevLine=%%a" 
127.
)) >"%Duplikate%" 
128.
 
129.
if %Cnt% gtr 0 ( 
130.
  findstr /v /g:"%Duplikate%" "%Datei%" > "%t%" && ( 
131.
    move "%t%" "%Datei%" > NUL 
132.
133.
134.
 
135.
del "%Duplikate%" >NUL 2>&1 
136.
 
137.
 
138.
::----Hier wird Schritt 7. (Statuswert wird verändert) durchgeführt - gute werden von 00 auf 10 gesetzt alle anderen (schlechten) auf 20 
139.
echo Schritt 7 
140.
 
141.
set "Status=00" 
142.
 
143.
(for /f "usebackq tokens=* delims=" %%i in ("%Datei%") do ( 
144.
   set "Z=%%i" 
145.
   set "Line=!Z:~0,50!" 
146.
   set "ReferenceNumber=!Z:~0,16!" 
147.
   set "HintererTeil=!Z:~20,30!" 
148.
 
149.
   if "!Line:~17,2!" equ "%Status%" ( 
150.
     echo !ReferenceNumber! 10 !HintererTeil! 
151.
   ) else ( 
152.
     echo !ReferenceNumber! 20 !HintererTeil! 
153.
154.
)) >"%t%" 
155.
 
156.
move "%t%" "%Datei%" > NUL
Ich habe den Doppelte-Zeilen-Finden-Algorithmus gewählt, den LotPings seinerzeit in dem von Dir schon gefundenen Thread veröffentlicht hat.

Als weitere Optimierungen habe ich sämtliche Unterprogramme beseitigt und bei allen FOR-Schleifen die Ausgabeumleitung aus dem Schleifenrumpf herausgeholt und auf die komplette Schleife gelegt. Dadurch muss die Ausgabedatei nur einmal zum Schreiben geöffnet werden. Das zusammen bringt sehr viel Performancegewinn.

Ich habe außerdem den Rat von jeb-the-batcher befolgt und den Kopf aller FOR-Schleifen, wo ein "delims=" stand, auf "tokens=* delims=" geändert.

Ob das Ergebnis Deinen Anforderungen entspricht kannst am besten Du selbst beurteilen. Ich poste hier mal die Ausgabedateien.

Die 123456789.txt
01.
1234567890000066 10 20121212162903 002 001 000 98 
02.
1234567890000067 10 20121212162905 002 001 000 98 
03.
1234567890000069 10 20121212163250 002 001 000 98 
04.
1234567890000070 10 20121212163344 002 001 000 98 
05.
1234567890000107 20 20121212163545 002 001 000 98 
06.
1234567890000108 20 20121212163730 002 001 000 98 
07.
1234567890000109 20 20121212163731 002 001 000 98 
08.
1234567890000111 20 20121212164046 001 002 000 98 
09.
1234567890000114 20 20121212164332 002 003 000 98 
10.
1234567890000115 20 20121212164333 003 001 000 98 
11.
1234567890000116 20 20121212164334 002 001 000 98 
12.
1234567890000117 10 20121212164335 003 001 000 98 
13.
1234567890000155 10 20121212165147 002 001 000 98 
14.
1234567890000156 10 20121212165728 003 001 000 98 
15.
1234567890000157 10 20121212165729 002 001 000 98 
16.
1234567890000158 20 20121212165730 001 000 000 98 
17.
1234567890000159 20 20121212165732 003 001 000 98 
18.
1234567890000160 10 20121212165734 002 001 000 98 
19.
1234567890000161 10 20121212165735 002 001 000 98 
20.
1234567890000162 10 20121212165736 002 001 000 98 
21.
1234567890000798 10 20121212184841 002 001 000 98 
22.
1234567890000802 20 20121212185510 002 005 000 98 
23.
1234567890000803 10 20121212185510 003 001 000 98 
24.
1234567890000804 10 20121212185510 002 001 000 98 
25.
1234567890002889 20 20121212191924 003 000 000 98 
26.
1234567890002890 20 20121212191926 002 001 000 98 
27.
1234567890002896 20 20121212194052 003 000 000 98 
28.
1234567890002897 20 20121212194054 002 000 000 98 
29.
1234567890005231 20 20121212193550 002 005 000 98
Die 123456789_13.01.2013_225939.err:
01.
2012.12.12.15.54.04~~1~1~1~1~1~0~1~0~0~0~2~0~8~2~0~0~0~0~0~0~0 
02.
2012.12.12.18.55.05~100000800220000~1~1~0~1~1~500~1~1~0~1~1~0~152~3~1~0~0~0~0~0~0 
03.
2012.12.12.19.40.36~~1~1~1~1~1~0~1~0~0~0~2~0~8~0~0~0~0~0~0~0~0 
04.
2012.12.12.19.40.42~~1~0~1~1~1~0~1~0~0~0~2~0~26~1~0~0~0~0~0~0~0
Gruß
Friemler
Bitte warten ..
Mitglied: UHU-stic
14.01.2013 um 09:39 Uhr
Mein lieber Herr Gesangsverein,

das nenne ich mal 'ne Performancesteigerung! Ich war so stolz, als ich durch eine Änderung in der Dublettenprüfung die Prozesszeit von 30 auf 15 MINUTEN reduziert hatte.
Die Steigerung durch das Script von Friemler ging von ~15 MINUTEN auf 4,5 SEKUNDEN !!!

Was soll ich sagen - DANKE!

Viele Grüße und weiter so

UHU-stic
Bitte warten ..
Mitglied: Friemler
14.01.2013 um 09:54 Uhr
Moin UHU-stic,

danke für die Blumen.

Ich habe mir heute Morgen mit frischem Kopf noch mal Gedanken zu der Dublettenprüfung gemacht. Wie mir scheint, tauchen doppelt vorkommende Zeilen in der Ausgabedatei garnicht mehr auf. Einmal sollten sie aber wohl auftauchen.

Melde Dich mal, ob das so ist, dann kann ich da noch nacharbeiten.

Gruß
Friemler
Bitte warten ..
Mitglied: UHU-stic
14.01.2013, aktualisiert um 10:34 Uhr
Moin Friemler,

also wenn ich das richtig sehe, dann sind die doppelten Einträge weiterhin drin - siehe Deine Ausgabedatei Zeile 8 & 9 bzw. 17 & 18.

Wenn Du da noch mal einen Blick riskieren würdest? Ich werde es parallel auch noch mal tun.

Merci

UHU-stic
Bitte warten ..
Mitglied: Friemler
14.01.2013 um 11:29 Uhr
Hallo UHU-stic,

ja, der Fehler war zwar genau anders herum, als ich dachte, aber ich hatte doch irgendwie das Gefühl, das an der Stelle noch was faul ist.

Anyway, ich habe das Script oben jetzt geändert und nochmal getestet, sollte funktionieren.

Gruß
Friemler
Bitte warten ..
Mitglied: UHU-stic
14.01.2013 um 13:43 Uhr
Mahlzeit Friemler,

na wenn das mal keine prompte Behandlung ist - und es denkt einer mit, somit nochmals: Vielen Dank!

Nun habe ich, durch den kleinen Duplettenfehler in Deinem Skript von gestern Nacht, nochmals alle Dupletten geprüft und dabei eine Besonderheit in meiner Testdatei bemerkt, die ich bis dato noch nicht gesehen hatte:
Eine Duplette hat teilweise einen inkonsitenten Status. Will meinen, dass Sie im Feld Status einmal den Status 0 (gut) und dann im nächsten Eintrag den Status ungleich 0 hat.
Ich habe dieses Szenario nun mal in Zeile 18 & 19 meiner Testdatei am Beispiel der Stücknummer 111 eingebaut.
Bei meiner ursprünglichen Duplettenabfrage schien immer der letzte (untere - nach dem Sort in Schritt 5) Eintrag in die Ergebnisdatei zu laufen - was dazu führte, dass es mir bis dato gar nicht aufgefallen war, nun läuft scheinbar der erste (oberste) Eintrag in die Ergebisdatei.

Somit wäre die "Logik" dass eine Duplette immer als ungültig gemeldet sein muss.
Ich würde da ja nun irgendwie in Schritt 6 ansetzen, in der Du mit Deiner Variable PrevLine ja momentan (weil bis dato so auch richtig) die 16 Stellen der ReferenceNumber abfragst. Man müsste nun, vermute ich, irgendwie noch das Statusfeld mit abfragen.

Wie kann man das nach Deiner Meinung am besten lösen?

Gruß - UHU-stic
Bitte warten ..
Mitglied: UHU-stic
14.01.2013, aktualisiert um 14:15 Uhr
Hallo Friemler, nochmal ich,

Habe nun die Zeile 123 aus Deinem Skript
echo %%a
gegen
echo !PrevLine!
getauscht und es behebt mein Problem / Fehler.
Birgt das Deiner Meinung nach andere Risiken? Ich habe bis dato immer nur zwei Einträge pro Stücknummer gesehen, jedoch befürchte ich, dass auch hier noch ungeantes Fehlerprotential schlummert...
Was wäre also wenn dort mehr als zwei Einträge stünden?
Bitte warten ..
Mitglied: Friemler
14.01.2013, aktualisiert um 19:54 Uhr
Hallo UHU-stic,

das wollte ich gerade fragen:

  • Sind das immer maximal 2 Zeilen oder können es auch mehr sein?
  • Ist es immer so, dass, wenn eine der Zeilen in der Status-Spalte einen Wert ungleich 00 hat, diese Zeile als zweites bzw. nach den Zeilen mit einem Wert gleich 00 kommt?

Du könntest ja die Zeile 123 durch
echo !PrevLine!&echo %%a
ersetzen und das Löschen der Duplikate.txt deaktivieren. Dann lass das Script über eine wirklich große Realworld-Eingabedatei laufen, die an die 60000 Einträge herankommt. Danach könntest Du mit einem neuen Batchfile, in das Du den Codeabschnitt der Dublettenerkennung hineinkopierst und etwas anpasst, die Duplikate.txt auf doppelte Zeilen untersuchen. Dabei prüfst Du dann aber nicht nur die ersten 16 Zeichen einer Zeile, sondern komplette Zeilen. Wenn Du dabei Dubletten findest, ist der Fall aufgetreten, dass es mehr als zwei Zeilen mit der gleichen ReferenceNumber gibt.

Btr. Deine Frage "Was passiert wenn es mehr als 2 Zeilen mit der gleichen ReferenceNumber gibt":
Das sollte kein Problem sein. Die Schleife vergleicht ja immer die aktuelle und die vorhergehende Zeile miteinander. Bei Gleichheit wird (nach Deiner Änderung) die Vorgängerzeile in die Duplikate.txt geschrieben. Der spätere Aufruf von FINDSTR sorgt dann dafür, dass alle Zeilen, die in der Duplikate.txt stehen, in der Ausgabedatei nicht mehr auftauchen. Somit würde von den Zeilen mit gleicher ReferenceNumber die als letztes in der Eingabedatei stehende in der Ausgabedatei auftauchen. Deshalb auch meine zweite Frage oben.

Gruß
Friemler
Bitte warten ..
Neuester Wissensbeitrag
Internet

Unbemerkt - Telekom Netzumschaltung! - BNG - Broadband Network Gateway

(3)

Erfahrungsbericht von ashnod zum Thema Internet ...

Ähnliche Inhalte
Perl
gelöst Mit Perl aus einer Datei teilidentische Zeilen löschen (5)

Frage von Jeduja zum Thema Perl ...

Windows Server
gelöst Windows ACL "Löschen verweigern" greift nicht - Datei lässt sich immer löschen (28)

Frage von Hastduschonneugestartet zum Thema Windows Server ...

Batch & Shell
Text-Datei auslesen und Inhalt als Parameter übergeben (1)

Frage von aubm2013 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 (12)

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 ...