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

Textdatei kürzen (Dos-Batchprogramm?)

Frage Entwicklung Batch & Shell

Mitglied: Richmen

Richmen (Level 1) - Jetzt verbinden

16.08.2007, aktualisiert 27.08.2007, 10003 Aufrufe, 16 Kommentare

Hallo,

ich habe zwar schon einige ähnliche Probleme gefunden, jedoch leider nichts für meins.

1) wir starten täglich etwa 20 Excel Makros, die sich gegenseitig aufrufen, d.h. es wird nur das erste manuell gestarten und danach läuft alles weitere auf einem Extra Rechner automatisch.
2) bei den zu verarbeitenden Dateien ist eine Textdatei mit momentan ca. 650.000 Zeilen. Diese sol in diverse Excel-Tabellen mit jeweils 65.000 Zeilen geladen werden.
3) momentan lesen wir die Textdatei zeilenweise, um jeweils 65000 Zeilen in eine neue Textdatei zu schreiben, die dann in Excel geöffnet wird.

Meine Überlegung war nun, beim Öffnen der Textdatei in Excel anzugeben, ab welcher Zeile eingelesen werden soll. Nach der Verarbeitung sollte dann die Textdatei gekürzt werden, um wieder die letzten 65.000 Zeilen zu lesen.

Ich möchte also gerne eine Textdatei kürzen, und zwar immer um 65000 Zeilen. Egal was in den Zeilen enthalten ist.
Mit VBA habe ich keine Möglichkeit dies zu tun, kennt jemand eine Lösung?

Vielleicht mit einem Batchprogramm??

Grüße,
Richard
Mitglied: bastla
16.08.2007 um 10:50 Uhr
Hallo Richmen!

Wenn schon kürzen, dann würde ich vorschlagen, dies am Anfang der Textdatei zu machen. Dazu genügt folgende Batchzeile:
01.
more +65000 Lang.txt > Kurz.txt
Grüße
bastla
Bitte warten ..
Mitglied: Richmen
16.08.2007 um 10:56 Uhr
Hallo bastla,

dann bekomme ich aber über 10 textdateien, die ich dann wiederum einlesen kann. Dies möchte ich vermeiden.
Damit wird die Datei ja nicht gekürzt, sondern einfach in deine neue geschrieben, sowas könnte ich auch gleich mit VBA realisieren.

Möchte nur die eine Textdatei behalten, und aus dieser eben Zeilen löschen.

Grüße,
Richard
Bitte warten ..
Mitglied: Biber
16.08.2007 um 11:09 Uhr
Moin Richie,

wenn doch aber die gesamte große Textdatei durch Makros verarbeitet wird und zwar logisch gesehen als 10 Dateien zu je 65000 Zeilen...

Wo ist denn der Vorteil, dass die Textdatei in dieser Schleife immer den gleichen Namen behält (nur mit einem immer kürzer werdenden Inhalt)??
Wartbarer wäre es wahrscheinlich schon, wenn die Monster.txt in kleinere Häppchen Monsterchen01.txt, Monsterchen02.txt,...Monsterchen10.txt physisch aufgesplittet werden würde.

Hinterher, nach kompletter Verarbeitung ist doch egal, ob dann eine Monster.txt oder 10 Monsterchenxx.txt gelöscht werden können, oder nicht?

Grüße
Biber
Bitte warten ..
Mitglied: bastla
16.08.2007 um 11:12 Uhr
Hallo Richmen!

Wenn Du nach der Verarbeitung wieder eine Lang.txt, aber mit 65000 Zeilen weniger haben willst, dann schreib eine zweite Batchzeile dazu:
01.
move Kurz.txt Lang.txt
... obwohl ich vermutlich ohnehin das Ganze in einem Arbeitsgang in VBA lösen würde - allerdings ist für mich das Ziel der Verabeitung (... in diverse Excel-Tabellen ...) noch zu wenig konkret.

Grüße
bastla
Bitte warten ..
Mitglied: Richmen
16.08.2007 um 11:28 Uhr
Ja Biber du hast grundsätzlich recht.
So ist der Prozess heute. Mein Chef möchte das aber gern geändert haben. Lösung hat er auch keine, aber das spielt für mich keine Rolle.. man kennt das ja
Somit ist es meine Aufgabe einfach eine Lösung zu finden, damit wir nicht jedes mal die monster.txt auf 10 textfiles splitten.

@Bastler
Also das hinundher schieben der Daten oder Dateien ist eine sehr unschöne Lösung.

Ja wie würdest du das in einem Arbeitsgang in VBA lösen, genau danach bin ich auf der Suche.
Was fehlt dir für das Ziel der Verarbeitung.
Wir nehmen praktisch nur die Daten aus der Textdatei und schreiben sie in Exceltabellen. Es wird nichts berechnet o.ä.
Was nicht sein soll ist ein Lineprozessing, da es bei 10x65.000 Zeilen sonst ewig dauert. Also nicht Zeile für Zeile schreiben, sondern auf einen Satz immer 65.000 in Excel einlesen.

Grüße,
Richard
Bitte warten ..
Mitglied: Biber
16.08.2007 um 11:32 Uhr
Moin Richie,

>Was nicht sein soll ist ein Lineprozessing, da es bei 10x65.000 Zeilen sonst ewig dauert. Also nicht Zeile für Zeile schreiben, sondern auf einen Satz immer 65.000 in Excel einlesen.
In eine Excel-Datei verteilt auf 10 Arbeitsblätter?
Kannst Du der Inputdatei ("Monster.txt") und der Exceldatei mal Pfade und Namen geben bitte?

Danke
Biber
Bitte warten ..
Mitglied: Richmen
16.08.2007 um 11:39 Uhr
Also wir werden die Excel Datei schon auf 10 Stück splitten.
Sonst müssen wir ja eine halbe Stunde warten bis die Datei geöffnet ist.

Die Excelfiles werden benannt:
Kros01.xls
Kros02.xls
Kros03.xls
...

Die Inputdatei ("Monster.txt") heisst:
KROS.ASC

Eine VBA Lösung dafür kennen wir hier keine..

Gruß,
Richard
Bitte warten ..
Mitglied: bastla
16.08.2007 um 21:21 Uhr
Hallo Richmen!

Eine blockweise Lösung nur mit Bordmitteln kann ich zwar nicht anbieten, aber vielleicht hilft auch der folgende VBA-Ansatz:
01.
Const QUELLE As String = "D:\Test" 
02.
Const ASCNAME As String = "KROS.ASC" 
03.
Const ZIEL As String = "D:\Test" 
04.
Const XLSNAME As String = "Kros" 
05.
 
06.
Sub Import() 
07.
x = Timer 
08.
 
09.
Set fso = CreateObject("Scripting.FileSystemObject") 
10.
If fso.FileExists(QUELLE & "\" & ASCNAME) Then 
11.
    aZeilen = Split(fso.OpenTextFile(QUELLE & "\" & ASCNAME, 1).ReadAll, vbCrLf) 'gesamte ASC-Datei einlesen 
12.
 
13.
    If fso.FileExists(ZIEL & "\" & XLSNAME & "01.xls") Then fso.DeleteFile ZIEL & "\" & XLSNAME & "??.xls" 'XLS-Dateien löschen 
14.
 
15.
    iLetzte = UBound(aZeilen) 'Zeilenanzahl - 1 
16.
    iDNr = 101 'Zähler für Dateinamen (nur letzte 2 Stellen verwenden) 
17.
    iZeile = 0 'Index für auszulesende Zeilen 
18.
    iMaxDatei = Int((iLetzte + 1) / 65536) 'Anzahl "volle" Tabellen ... 
19.
    If (iMaxDatei * 65536) < (iLetzte + 1) Then iMaxDatei = iMaxDatei + 1 '... und noch eine für den Rest 
20.
    Dim W As Workbook 
21.
     
22.
    For iDatei = 1 To iMaxDatei - 1 'Alle vollen Tabellen ... 
23.
        Set W = Workbooks.Add 
24.
        W.Activate 
25.
        With W.Worksheets(1) 
26.
            For j = 1 To 65536 
27.
                .Cells(j, 1) = aZeilen(iZeile) 
28.
                iZeile = iZeile + 1 
29.
            Next 
30.
        End With 
31.
        AufteilenUndSpeichern W, Right(CStr(iDNr), 2) 
32.
        iDNr = iDNr + 1 
33.
    Next 
34.
     
35.
    If iZeile <= iLetzte Then '... und der Rest 
36.
        Set W = Workbooks.Add 
37.
        W.Activate 
38.
        With W.Worksheets(1) 
39.
            j = 1 
40.
            Do While iZeile <= iLetzte 
41.
                .Cells(j, 1) = aZeilen(iZeile) 
42.
                iZeile = iZeile + 1 
43.
                j = j + 1 
44.
            Loop 
45.
        End With 
46.
        AufteilenUndSpeichern W, Right(CStr(iDNr), 2) 
47.
    End If 
48.
Else 
49.
    MsgBox QUELLE & "\" & ASCNAME & " nicht gefunden!", vbCritical 
50.
End If 
51.
MsgBox "Gesamtlaufzeit: " & Timer - x 
52.
End Sub 
53.
 
54.
Sub AufteilenUndSpeichern(WB As Workbook, sNummer As String) 
55.
'Spalte A mit eingelesener Textzeile mittels "Text in Spalten" aufteilen 
56.
WB.Worksheets(1).Columns("A:A").TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _ 
57.
    TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _ 
58.
    Semicolon:=True, Comma:=False, Space:=False, Other:=False, FieldInfo _ 
59.
    :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1)), TrailingMinusNumbers:=True 
60.
 
61.
WB.SaveAs ZIEL & "\" & XLSNAME & sNummer & ".xls" 'Datei speichern ... 
62.
WB.Close '... und schließen. 
63.
End Sub
Da Du zum Trennzeichen keine Angaben gemacht hast, bin ich von Semikolon ausgegangen (siehe im "Sub Aufteilen" den vom Makrorecorder gelieferten "TextToColumns"-Teil).

Bei meinen Tests auf einem Dual-Core-Rechner (mit ausreichend Speicher!, da die Textdatei vollständig in den Speicher geladen wird) wurden 655.000 Zeilen mit je 4 Feldern (gesamte Satzlänge 70 Zeichen) in etwa 4 Minuten eingelesen und gespeichert.

Grüße
bastla

P.S.: Am Code lässt sich sicher noch einiges ergänzen (Errorhandling) / optimieren / verschönern...
Bitte warten ..
Mitglied: Richmen
17.08.2007 um 10:18 Uhr
Hi bastla,

wenn ich mir das "trocken" ansehe sieht das ganz gut aus. Leider läuft es bei mir nicht.
Ich bekomme bei dem readall einen Fehler:
Laufzeitfehler '-2147417848(80010108)':
Die Methode 'ReadAll' für das Objekt 'ITextStream' ist fehlgeschlagen.

Hast du eine Idee woran das liegen könnte.

Vielen Dank für deine Hilfe!

Rich
Bitte warten ..
Mitglied: bastla
17.08.2007 um 10:37 Uhr
Hallo Richmen!

Mit der Beschreibung des Fehlers
01.
80010108 2147549448 RPC_E_DISCONNECTED: The object invoked has disconnected from its clients.
kann ich leider nicht wirklich etwas anfangen ...

Versuch das Ganze einmal als VB-Script anzutesten, um zu sehen, ob der Fehler auch unabhängig von Excel auftaucht:
01.
Const QUELLE = "D:\Test" 
02.
Const ASCNAME = "KROS.ASC" 
03.
 
04.
Set fso = CreateObject("Scripting.FileSystemObject") 
05.
aZeilen = Split(fso.OpenTextFile(QUELLE & "\" & ASCNAME, 1).ReadAll, vbCrLf) 
06.
MsgBox "Eingelesen"
Das Einlesen meiner Testdatei (wie groß ist übrigens Deine Datendatei?) von einer lokalen Platte dauert so etwa 10 Sekunden ...

Grüße
bastla
Bitte warten ..
Mitglied: Richmen
17.08.2007 um 11:00 Uhr
Dachte ich mir schon, aber einen Versuchs wars Wert!

Ja leider habe ich den gleichen Fehler wieder.
Die Datei hat etwas über 250MB.

Wenn ich die Textdatei mit einem Doppelklick öffne dauerts auch ca 10 sekunden bis sie offen ist.

Ich habe einen P4 mit 2.8 ghz und 1GB Ram.
Bitte warten ..
Mitglied: bastla
17.08.2007 um 11:21 Uhr
Hallo Richmen!

Dann sieht es fast so aus, als müsstest Du doch sequentiell einlesen - vielleicht komme ich später dazu, das Script noch in diese Richtung umzuschreiben ...

Grüße
bastla
Bitte warten ..
Mitglied: Richmen
17.08.2007 um 11:39 Uhr
Hallo bastla,

ich habe nun auch einen anderen Lösungsvorschlag bekommen.
01.
Dim fHandle As Long 
02.
Dim sFile As String 
03.
Dim nBytes As Long 
04.
   
05.
' Datei, die "gekürzt" werden soll 
06.
sFile = "c:\temp\MyFile.dat" 
07.
   
08.
' Anzahl Bytes die am Ende entfernt werden sollen 
09.
nBytes = 10 
10.
   
11.
' Datei öffnen und Handle erstellen 
12.
fHandle = CreateFile(sFile, GENERIC_WRITE, _ 
13.
  FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, _ 
14.
  FILE_FLAG_SEQUENTIAL_SCAN, 0&) 
15.
 
16.
If fHandle > 0 Then 
17.
  ' Dateizeiger an die gewünschte Position setzen 
18.
  Call SetFilePointer(fHandle, -nBytes, ByVal 0&, FILE_END) 
19.
     
20.
  ' Aktuelle Position als "END-Position" setzen 
21.
  Call SetEndOfFile(fHandle) 
22.
     
23.
  ' Datei schließen 
24.
  Call CloseHandle(fHandle) 
25.
Else 
26.
  ' Fehler: Evtl. existiert die Datei nicht... 
27.
End If
Muss mir das mal genauer ansehen, aber dies könnte auch funktionieren.

Dein Weg gefällt mir aber auch gut, die Laufzeit würde mich interessieren!..
Bitte warten ..
Mitglied: bastla
17.08.2007 um 11:56 Uhr
Hallo Richmen!

Als Anmerkung zum alternativen Lösungsvorschlag:
Wenn die Aufteilung nicht nach Zeilen, sondern nur nach Speicherplatz (Bytes) erfolgen dürfte, wäre es natürlich einfacher - dann könntest Du außerdem ein beliebiges "Filesplit"-Utility verwenden, um passend große Textdateien zu erhalten ...

Grüße
bastla
Bitte warten ..
Mitglied: bastla
17.08.2007 um 12:51 Uhr
Hallo Richmen!

Die sequentielle Version (ist bei mir übrigens auch kaum langsamer) - zur Sicherheit ohne Verwendung des "FileSystemObject":
01.
Const QUELLE As String = "D:\Test" 
02.
Const ASCNAME As String = "KROS.ASC" 
03.
Const ZIEL As String = "D:\Test" 
04.
Const XLSNAME As String = "Kros" 
05.
 
06.
Sub ImportSequ() 
07.
x = Timer 
08.
 
09.
sQ = Dir(QUELLE & "\" & ASCNAME) 
10.
If sQ <> "" Then 
11.
    sZ = Dir(ZIEL & "\" & XLSNAME & "01.xls") 
12.
    If sZ <> "" Then Kill ZIEL & "\" & XLSNAME & "??.xls" 'XLS-Dateien löschen 
13.
 
14.
    Open QUELLE & "\" & ASCNAME For Input As 1 
15.
    iDNr = 101 'Zähler für Dateinamen (nur letzte 2 Stellen verwenden) 
16.
    j = 1 
17.
    Dim W As Workbook 
18.
    Set W = Workbooks.Add 
19.
    W.Worksheets(1).Activate 
20.
 
21.
    Do While Not EOF(1) 
22.
        If j <= 65536 Then 
23.
            Line Input #1, sZeile 
24.
            W.Worksheets(1).Cells(j, 1) = sZeile 
25.
            j = j + 1 
26.
        Else 
27.
            AufteilenUndSpeichern W, Right(CStr(iDNr), 2) 
28.
            iDNr = iDNr + 1 
29.
            j = 1 
30.
            Set W = Workbooks.Add 
31.
            W.Activate 
32.
        End If 
33.
    Loop 
34.
 
35.
    AufteilenUndSpeichern W, Right(CStr(iDNr), 2) 'Die letzte Datei auch noch speichern ... 
36.
    Close 1 
37.
 
38.
Else 
39.
    MsgBox QUELLE & "\" & ASCNAME & " nicht gefunden!", vbCritical 
40.
End If 
41.
 
42.
MsgBox "Gesamtlaufzeit: " & Timer - x 
43.
End Sub 
44.
 
45.
 
46.
Sub AufteilenUndSpeichern(WB As Workbook, sNummer As String) 
47.
'Spalte A mit eingelesener Textzeile mittels "Text in Spalten" aufteilen 
48.
WB.Worksheets(1).Columns("A:A").TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _ 
49.
    TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _ 
50.
    Semicolon:=True, Comma:=False, Space:=False, Other:=False, FieldInfo _ 
51.
    :=Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1)), TrailingMinusNumbers:=True 
52.
WB.SaveAs ZIEL & "\" & XLSNAME & sNummer & ".xls" 'Datei speichern ... 
53.
WB.Close '... und schließen. 
54.
End Sub
Grüße
bastla
Bitte warten ..
Mitglied: Richmen
27.08.2007 um 08:14 Uhr
So..


erstmal sorry dass ich mich erst jetzt wieder melde. Aber ich hatte die letzten Tage echt viel um die Ohren.
Leider hab ich es auch noch nicht geschafft das Programm zu testen. Habs aber nicht vergessen.

Habe es schonmal in einem kleinen Projekt laufen lassen, und da sah das ergebnis gut aus.

Es kann noch ein bisschen dauern bevor ich es in dem richtigen Projekt unterbringen kann, darum schreib ich schonmal vorab hier rein.

Also vielen Dank an dieser Stelle für eure Hilfe!!!!

Sollte es nicht laufen oder ich noch Probleme damit haben, werdet ihr sowieso von mir hören!

Vielen Dank!

Rich
Bitte warten ..
Neuester Wissensbeitrag
CPU, RAM, Mainboards

Angetestet: PC Engines APU 3a2 im Rack-Gehäuse

(1)

Erfahrungsbericht von ashnod zum Thema CPU, RAM, Mainboards ...

Ähnliche Inhalte
Batch & Shell
Powershell - In Textdatei suchen und ersetzen (1)

Frage von Raaja89 zum Thema Batch & Shell ...

Java
gelöst Textdatei in Array speichern (zeilenweise) (1)

Frage von Bruchsal zum Thema Java ...

Heiß diskutierte Inhalte
DSL, VDSL
DSL-Signal bewerten (13)

Frage von SarekHL zum Thema DSL, VDSL ...

Switche und Hubs
Trunk für 2xCisco Switch. Wo liegt der Fehler? (13)

Frage von JayyyH zum Thema Switche und Hubs ...

Windows Server
Mailserver auf Windows Server 2012 (9)

Frage von StefanT81 zum Thema Windows Server ...

Backup
Clients als Server missbrauchen? (9)

Frage von 1410640014 zum Thema Backup ...