bernd8183
Goto Top

Dateieigenschaften von txt-files wie Dateikodierung und darin verwendetes Trennzeichen (Tab , Komma etc) via batch-Datei auslesen und in neues textfile schreiben

Hallo,

nachdem mir hier schon mal geholfen wurde, wende ich mich mit meinen Fragen wieder mal an euch face-smile

In einem Verzeichnis stehen u.a. mehrere tausend txt-files, die automatisch erzeugt werden.


Aus unerfindlichen Gründen werden diese Dateien mal mit encoding UTF-8 , mal als ANSI geliefert.
Außerdem ändert sich auch das in den txtfiles verwendete Trennzeichen. Mal wird in den Dateien das Trennzeichen TABULATOR verwendet , mal das Trennzeichen KOMMA.

Um nun herauszufinden wieviele Txt-files in welcher Variante vorliegen, möchte ich diese Eigenschaften der Dateien gerne per batch auslesen und in eine Zieldatei schreiben.

ich bin mir nicht sicher ob ich mein Thema im richtigen Bereich eingestellt habe....

Bin für alle Vorschläge dankbar...


Grüsse Bernd

Content-Key: 187738

Url: https://administrator.de/contentid/187738

Printed on: April 19, 2024 at 00:04 o'clock

Member: TsukiSan
TsukiSan Jul 10, 2012 at 14:44:09 (UTC)
Goto Top
Hallo Bernd,

irgendetwas gibt mir zu denken! Kannst du mal - wenn ich richtig mit gezählt habe - 2 Beispieltextdateien liefern - nee, eigentlich 4! - die alle Möglichkeiten aufzeigen?
Du schreibst von Textdateien. Wie sehen die aus, wenn man die öffnet? Stehen da nur Zahlenwerte drinnen? Kann ich mir nicht vorstellen, weil wenn die strickt in den besagten Formaten vorliegen, sind die Trennzeichen ja auch in entsprechenden Formaten ausgeführt.
Also, das ganze verwirrt mich etwas.
Nur mal als Beispiel: Der Buchstabe A ist im UTF-8 Format 41 und in ANSI 65.
UTF-8 41 ergibt binär 01000001 und das entspricht dezimal 65. Damit sind wir bei gleichem
Ergebnis.

Gruss
Tsuki
Mitglied: 76109
76109 Jul 10, 2012 updated at 20:59:31 (UTC)
Goto Top
Hallo Bernd, Hallo Tsuki!

Hier schonmal vorab der VBS-Code zum Konvertieren von UTF-8 und UTF-16-Dateien ins ANSI-Format:
Option Explicit

Const CharSetIdUTF8 = "EFBBBF"  
Const CharSetIdUTF16BE = "FEFF"  
Const CharSetIdUTF16LE = "FFFE"  
Const CharSetIdUTF32BE = "0000FEFF"  
Const CharSetIdUTF32LE = "FFFE0000"  

Const adTypeBinary = 1
Const adTypeText = 2
Const adSaveCreateOverWrite = 2


'Main Begin  

'Call FileConvertUTFToAnsi("Dateipfad")  

'Main End  


Sub FileConvertUtfToAnsi(ByRef File)
    Dim oFso, oBinaryStream, aBytes, sCharSetId, sCharSet, sText

    Set oFso = CreateObject("Scripting.FileSystemObject")  
    
    'Die ersten 3 Bytes (Dateikennung) der Datei einlesen  
    With oFso.OpenTextFile(File)
        sText = .Read(3)
       .Close
    End With
    
    'Dateityp-Kennung  
    sCharSetId = Hex(Asc(Left(sText, 1))) & Hex(Asc(Mid(sText, 2, 1))) & Hex(Asc(Right(sText, 1)))
    
    'Nur Dateityp UTF-8 und UTF-16 konvertieren  
    If sCharSetId = CharSetIdUTF8 Then
        sCharSet = "UTF-8"  
    ElseIf sCharSetId = Left(CharSetIdUTF32LE, 3) Then
        Exit Sub
    ElseIf Left(sCharSetId, 2) = CharSetIdUTF16BE Then
        sCharSet = "UTF-16"  
    ElseIf Left(sCharSetId, 2) = CharSetIdUTF16LE Then
        sCharSet = "UTF-16"  
    Else
        Exit Sub
    End If
    
    Set oBinaryStream = CreateObject("ADODB.Stream")  
    
    With oBinaryStream      'UTF-8/UTF-16-Datei in Byte-Array einlesen  
        .Type = adTypeText
        .Charset = sCharSet
        .Open
        .LoadFromFile File
         aBytes = .ReadText
        .Close
    End With
    
    With oBinaryStream      'Byte-Array im Ansi-Format in Datei schreiben  
        .Type = adTypeText
        .Charset = "x-Ansi"  
        .Open
        .WriteText aBytes
        .SaveToFile File, adSaveCreateOverWrite
        .Close
    End With
End Sub

@tsuki
Und den Rest darfst Du machenface-wink

Gruß Dieter
Member: TsukiSan
TsukiSan Jul 10, 2012 at 22:13:56 (UTC)
Goto Top
Hallo Dieter,

danke für den Code. Den werde ich mir mal abspeichern face-wink

Allerdings will der TO nichts konvertieren, sondern
Um nun herauszufinden wieviele Txt-files in welcher Variante vorliegen, möchte ich diese Eigenschaften der Dateien gerne per batch auslesen und in eine Zieldatei schreiben.

Also für mich wäre mal 2 Beipiel-dateien mit UTF-8 und ANSI und davon je 2 Beispiele mit KOMMA und TABULATOR.
Dann könnte man(n) - Frau auch - eventuell nach Anhaltspunkten suchen und somit eine Auswertung vornehmen.

Gruss
Tsuki face-smile
Member: bernd8183
bernd8183 Jul 11, 2012 at 05:44:31 (UTC)
Goto Top
hallo und danke für die ersten antworten...

die dateien sehen aus wie folgt:

datei mit komma als trennzeichen:

BasisberichtKOMMA

Filter1:
blabla

Filter2:
blabla

Produktionsjahr,Produktionsmonat,,Metriken,Produzierte Teile,Anzahl Beanstandungen,Gesamtkosten,1,3,6,9,12,18,24,30,36,48,60,72,84,96,108,120
2011,Juni 2011,-13,,23,0,0,0,00,0,00,0,00,0,00,0,00,,,,,,,,,,,
2011,Juli 2011,-12,,121,0,0,0,00,0,00,0,00,0,00,0,00,,,,,,,,,,,
2011,August 2011,-11,,145,4,4.693,0,00,0,00,0,40,2,83,,,,,,,,,,,,
2011,September 2011,-10,,202,3,618,0,00,0,00,2,04,3,06,,,,,,,,,,,,
2011,Oktober 2011,-9,,62,3,410,0,00,1,10,4,57,6,62,,,,,,,,,,,,
2011,November 2011,-8,,147,2,215,0,00,0,00,1,46,,,,,,,,,,,,,
2011,Dezember 2011,-7,,1.526,22,10.344,0,00,0,40,6,78,,,,,,,,,,,,,
2011,Gesamt,,,2.226,34,16.280,0,00,0,30,5,08,2,60,0,00,,,,,,,,,,,
2011,Kosten pro Beanstandung,,,,,479,,,,,,,,,,,,,,,,
2012,Januar 2012,-6,,4.837,76,23.606,0,17,3,17,4,88,,,,,,,,,,,,,
2012,Februar 2012,-5,,6.657,43,17.467,1,98,2,50,,,,,,,,,,,,,,
2012,März 2012,-4,,6.580,14,17.623,1,61,2,65,,,,,,,,,,,,,,
2012,April 2012,-3,,6.596,5,4.714,0,01,0,71,,,,,,,,,,,,,,
2012,Mai 2012,-2,,7.623,6,4.134,0,03,,,,,,,,,,,,,,,
2012,Juni 2012,-1,,7.666,0,0,0,00,,,,,,,,,,,,,,,
2012,Juli 2012,0,,1.621,0,0,,,,,,,,,,,,,,,,
2012,Gesamt,,,41.580,144,67.544,0,62,2,20,4,88,,,,,,,,,,,,,
2012,Kosten pro Beanstandung,,,,,469,,,,,,,,,,,,,,,,
Gesamt,,,,43.806,178,83.824,0,59,2,04,4,94,2,60,0,00,,,,,,,,,,,
Kosten pro Beanstandung,,,,,,471,,,,,,,,,,,,,,,,




datei mit tab als trennzeichen


BasisberichtTAB

Filter1:
blabla

Filter2:
blabla

Produktionsjahr Produktionsmonat Metriken Anzahl prod Anzahl beanst Anzahl Beanstandungen 1 3 6 9 12 18 24 30 36 48 60 72 84 96 108 120
2011 September 2011 413 0 0 0,0000 0,0000 0,0000 0,0000
2011 Oktober 2011 3.107 0 0 0,0000 0,0000 0,0000 0,0000
2011 November 2011 7.526 1 1 0,0133 0,0133 0,0133
2011 Dezember 2011 6.539 1 1 0,0000 0,0153 0,0153
2011 Gesamt 17.585 2 2 0,0057 0,0114 0,0114 0,0000
2012 Januar 2012 9.166 2 2 0,0000 0,0218 0,0218
2012 Februar 2012 11.569 1 1 0,0000 0,0000
2012 März 2012 12.183 2 2 0,0000 0,0164
2012 April 2012 11.757 1 1 0,0085 0,0085
2012 Mai 2012 13.521 0 0 0,0000
2012 Juni 2012 12.832 0 0 0,0000
2012 Juli 2012 0 0 0
2012 Gesamt 71.028 6 6 0,0014 0,0112 0,0218
Gesamt 88.613 8 8 0,0023 0,0112 0,0150 0,0000


Sorry habe leider nicht gefunden wie ich die Dateien hier hochladen kann... Ích kann die files aber gerne auch per mail senden...
Mitglied: 76109
76109 Jul 11, 2012 updated at 08:25:09 (UTC)
Goto Top
Hallo bernd8183!

Wenn alle Dateien den gleichen Kontext beinhalten, dann kann man das anhand der Anzahl Tokens ermitteln und die Dateien gegebenenfalls durch Dateien mit einem einheitlichen Trennzeichen ersetzen.

Beispiel:
Token = Split(Textzeile, ","): If UBound(Token) = BestimmteAnzahl Then Trennzeichen = ',' .....

Beginnen die betreffenden Zeilen immer mit 'Produktionsjahr' und enden mit 'Gesamt'?

Gruß Dieter
Member: TsukiSan
TsukiSan Jul 11, 2012 updated at 09:22:29 (UTC)
Goto Top
Na seh'n S'e,

ist doch gleich ein ganz anderer Sachverhalt face-wink

Ich denke mal, die Idee von Dieter ist das eleganteste.
Einfach die gesamte Datei öffnen, beide Möglichkeiten (KOMMA oder TABULATOR)
ersetzen durch das Trennzeichen seines Vertrauens und fertig ist die Sache.
Mann kann natürlich vorher noch raussuchen, welche Datei was für ein Trennzeichen hat(te), aber da stellt sich mir die Frage nach der Sinnhaftigkeit. Ich denke, man(n) hat doch schon genug zu tun auf der Arbeit und schlägt sich mit genug Staistiken etc. pepe herum face-wink

Viele Grüße

Tsuki
Member: bernd8183
bernd8183 Jul 11, 2012 at 12:30:18 (UTC)
Goto Top
Danke für die Tipps, allerdings war es nicht mein Ziel die Trennzeichen zu reparieren. Hintergrund ist der daß seit nem update eine Applikation Dateien mit Trennzeichen Komma statt Trennzeichen Tab ausspuckt. Seltsamerweise werden aber nicht alle Dateien falsch geliefert sondern nur ein Teil. Diese Dateien werden in einem Tool weiter verarbeitet und der Dateiparser läuft auf Error wenn die Datei "nicht UTF-8" und das Trennzeichen gleich Komma ist.
Um jetzt herauszufinden wie groß der Schaden ist wollte ich die Trennzeichen und Kodierung aus Datei bzw. Dateieigenschaften auslesen.

Mein Workaround von heute mittag:

Windows-Suche mit eindeutigem Kennzeichen innerhalb der Datei für falsch gelieferte Dateien (hier ,, (KommaKomma)

Suche bei 60000 Dateien dauert ziemlich lange, aber liefert ein Ergebnis.


Um das Suchergebnis weiter zu verarbeiten, exportiere ich das Suchergebnis mit dem tool sysexporter.
Somit habe ich eine Liste mit Dateiname, Ordner, Mod-Date, etc.

Und das sind die Daten die ich für mein Monitoring brauche.

Schön wäre es wenn man das mit ner batch und nem nächtlichen Schedule automatisieren könnte. Vielleicht hat jemand noch nen Tipp wie ich die zeitraubende Windowssuche nachts laufen lassen kann....


Danke
Member: TsukiSan
TsukiSan Jul 11, 2012 updated at 13:30:36 (UTC)
Goto Top
Hallo Bernd,

das ist sich gar nicht so mit ohne face-wink

Jetzt nehme ich mal an, du suchst nach Doppelkomma und das wäre ein Indiz dafür, dass etwas faul ist mit deiner Datei. Dann hätte ich zum spielen folgenden VBS-Schnipsel, den du mit einer Batch-Datei aufrufst und die Ergebnisse in eine Datei umleitest.
Nehmen wir an, du benamst dein VBS-Datei: "Meine.VBS" dann rufst du im gleichen Ordner
der VBS-Datei mittels ein Batch-Datei die VBS auf:
CScript Meine.VBS //NOLOGO >>Ergebnis.txt

In die VBS fügst du diesen Schnipsel ein:
Dim FSO
Dim Ordner, Pfad
Dim Suchzeichen

Suchzeichen = ",,"  
Pfad = "C:\TestOrdner"  
Set FSO = CreateObject("Scripting.FileSystemObject")  

Set Ordner = FSO.getfolder(Pfad)
    For Each File In Ordner.Files
        Pfadangabe = File.Path
        Set AktuelleDatei = FSO.OpenTextFile(Pfadangabe, 1)
		AktuelleDaten = Split(AktuelleDatei.ReadAll,Suchzeichen)
		If Ubound(AktuelleDaten) > 0 Then
			Wscript.Echo "Die Datei [" & Pfadangabe & "] enthaelt falsche Trennzeichen!"  
		End If
        AktuelleDatei.Close
    Next

Set FSO = Nothing
Hier musst du noch den Pfad anpassen! Und zwar muss dort hinein, wo deine rund 60000 Dateien abgelegt sind.
Die Batch und die VBS würde ich in einen anderen Ordner ablegen.

Nun, wenn das soweit das tut, was du erst einmal möchtest, kannst du mit einem Taskplaner von Windows die Batch zu jeder Uhrzeit starten, die dir recht ist und dann den Rechner nachts arbeiten lassen.

Solong erst einmal und viele Grüße

Tsuki

[Edit]
Ups, noch ein ">" in die Batch eingefügt face-wink
[/Edit]
Mitglied: 76109
76109 Jul 11, 2012 updated at 13:42:18 (UTC)
Goto Top
Hallo Tsuki!

Ich denke, dass Dilemma mit den Kommas sind falsche Zahlenwerte und von daher sollte es nicht mit Split, sondern anhand einer größeren Anzahl aufeinnanderfolgender Kommas hin geprüft werden. Kann mich natürlich auch irren und wenn, dann ist ein Test auf UBound gerade mal > 0 auf jeden Fall zu wenig

Gruß Dieter
Member: TsukiSan
TsukiSan Jul 11, 2012 at 13:43:45 (UTC)
Goto Top
Hallo Dieter,

genau soetwas vermute ich auch. Die beiden Beispieldatensätze lassen kein eindeutiges Muster erkennen, wie ein Programm explizit auf etwas aufmerksam werden soll.
Weil wenn man nur nach KOMMA-trennung sucht, stören Realwerte/Doubles etc. die mit Komma als Trenzeichen enthalten sind (andere sind wieder durch PUNKT getrennt).
Also bezugnehmend auf die letzte Info vom TO: da werden Doppelkommas angemeckert. Das ist dann schon mal ein Hint face-wink

Ich würde mal sagen, lass ihn mal die Dateien mit meinem Schnipsel durchsuchen und auflisten. Mal sehen, was dabei rumkommt. Ein gutes Gefühl habe ich immer noch nicht, aber es interessiert halt face-wink

Viele Grüße

Tsuki
Member: bastla
bastla Jul 11, 2012 updated at 14:04:30 (UTC)
Goto Top
Hallo @all!

Vielleicht auch andersrum: Wie hoch ist die Wahrscheinlichkeit, dass Dateien, die nicht TAB-getrennt sind, TAB beinhalten? Letzteres festszustellen benötigt gar kein Split() sondern ist einfach per InStr() zu realisieren ...

Grüße
bastla

P.S.: Da in der Schleife die Datei ja schon als Objekt vorliegt, kann sie einfach mit "File.OpenAsTextStream.ReadAll" eingelesen werden ...
Member: TsukiSan
TsukiSan Jul 11, 2012 updated at 14:11:40 (UTC)
Goto Top
Hallo bastla,

deine Überlegung kommt auch noch hinzu! Das meinte ich, dass ich noch kein gutes Gefühl habe bei der ganzen Sache.
Es gibt - laut TO - zu viele Kombinationen/Möglichkeiten. Sowas kann ein Prozessor nur ganz umständlich/hässlich abfangen face-wink

Gruss
Tsuki

Ps.: Weil neulich angesprochen von bastla kann die Zeile15 oben durch
Wscript.Echo "Die Datei [" & Fso.GetBaseName(Pfadangabe) & "] enthaelt falsche Trennzeichen!"  
ersetzt werden face-wink
Member: bernd8183
bernd8183 Jul 12, 2012 at 09:01:05 (UTC)
Goto Top
HAllo Tsuki,

das Skript läuft super, Danke... Habe in die Textausgabe noch das ModificationDate der jeweiligen Datei eingebaut

ModDate =File.DateLastModified
Wscript.Echo "[" & Pfadangabe &"] ["& ModDate &"] [Delimiter=Komma]"

Wenn auch jetzt noch die Dateien in den Subfolders (unter Pfad = "C:\TestOrdner" ) berücksichtigt werden könnten , dann wäre ich GLÜCKLICH face-smile
Member: TsukiSan
TsukiSan Jul 12, 2012 updated at 16:18:06 (UTC)
Goto Top
Hallo Bernd,

na es freud mich, wenn es bei dir klappt face-wink

Um alle Unterordner einzubeziehen könnte man das ganze Script so aufbauen:
Dim FSO
Dim Ordner, Pfad
Dim Suchzeichen

Suchzeichen = ",,"  
Pfad = "C:\TestOrdner"  
Set FSO = CreateObject("Scripting.FileSystemObject")  

DateienEinlesen(Pfad) 'hier die Sub-Routine aufrufen  

Private Sub DateienEinlesen(tempPfad)
Set Ordner = FSO.getfolder(tempPfad)
    For Each File In Ordner.Files
        Pfadangabe = File.Path
        Set AktuelleDatei = FSO.OpenTextFile(Pfadangabe, 1)
		AktuelleDaten = Split(AktuelleDatei.ReadAll,Suchzeichen)
		If Ubound(AktuelleDaten) > 0 Then
			'Wscript.Echo "Die Datei [" & Pfadangabe & "] enthaelt falsche Trennzeichen!"  
			Wscript.Echo "Die Datei [" & Fso.GetBaseName(Pfadangabe) & "] enthaelt falsche Trennzeichen!"  
		End If
        AktuelleDatei.Close
    Next

   For Each Unterordner In Ordner.SubFolders
        Ordner = Unterordner.Path
        DateienEinlesen (Ordner)
   Next
End Sub

Set FSO = Nothing
Set Ordner = Nothing
Set AktuelleDatei = Nothing
dann einfach deinen Zweizeiler dazu/ersetzen und es müsste funktionieren.

Viele Grüße

Tsuki
Member: bernd8183
bernd8183 Jul 13, 2012 at 09:55:08 (UTC)
Goto Top
Hallo an alle!

hat geklappt.. zumindest mit lokalen Laufwerken. Liegen die Dateien auf nem share, muß ich bestimmt per vbs noch ein netzlaufwerk mappen...

na ja.. da such ich nächste Woche mal danach face-smile

Jetzt ist erst mal Wochenende.

Danke nochmal und Viele Grüße


Bernd
Member: bastla
bastla Jul 13, 2012 at 11:24:14 (UTC)
Goto Top
Hallo bernd8183!
Liegen die Dateien auf nem share, muß ich bestimmt per vbs noch ein netzlaufwerk mappen...
UNC?

Grüße
bastla
Member: bernd8183
bernd8183 Jul 14, 2012 at 08:15:24 (UTC)
Goto Top
Hallo Bastla,

ja... (\\server\xyz\Folder\)


hab gestern noch versucht in meiner Trennzeichen.bat ein Netzlaufwerk zu verbinden (\\server\xyz\Folder\) und dann in meine.vbs auf den gemappten Laufwerksbuchtaben zuzugreifen. Hat aber nicht geklappt...

Gruß Bernd
Member: TsukiSan
TsukiSan Jul 14, 2012 at 09:11:03 (UTC)
Goto Top
Hallo Bernd,

bastla meint es etwas anders.

Spiel mal mit dieser Pfadangabe etwas herum:
file:///D:/Dokumente/HTML/blablabla.bla

Gruss
Tsuki
Member: bernd8183
bernd8183 Jul 16, 2012 at 14:03:41 (UTC)
Goto Top
Mein Problem ist gelöst ... Bei mir lag es an der Groß- / Kleinschreibung bei der Pfadangabe

Jetzt läuft alles wie es soll!

Danke für die Hilfe und schöne Grüße