-jenzz-
Goto Top

Zeilenweises Verarbeiten mehrerer Flatfiles in einem Batch-Skript mit Bordmitteln (Windows Shell)

Hallo liebe Gemeinde,

ich bin neu hier und wende mich mit einem Problem an euch, das ich einfach nicht in den Griff bekomme. Es sieht folgendermaßen aus:

Es soll eine automatische Verarbeitung mehrerer Flatfiles (ASCII) in einem definierten Verzeichnis stattfinden. Die Anzahl der Dateien innerhalb des Verzeichnisses sind im Vorfeld nicht bekannt, richten sich aber nach einem bestimmten Muster (TDWH*.*). Die Dateien werden täglich geliefert.

Mein Problem ist nun Folgendes: im Dateinamen der Flatfiles befindet sich eine Information, die ich in jede Zeile des entsprechenden Files an den Anfang (oder das Ende) stellen will. Ich habe schon von mehreren Seiten gehört, dass dies durch ein VBScript durchaus elegant machbar ist. Meine Herausforderung ist die, das mit den normalen Bordmitteln einer Windows Server 2003 - Installation hinzubekommen. Es gibt in dieser Umgebung keine PowerShell oder sonstige Tools, die extra installiert worden sind, d.h. sed-Befehle (usw.) sind nicht möglich.

Im Anschluß an die Bearbeitung dieser Dateien soll der (bearbeitete) Inhalt aller Dateien in eine neue Datei geschrieben werden, die dann zur Verarbeitung in ein DWH weiter gereicht wird.

Ich habe in diesem Forum schon ein paar Anleitungen durchgelesen, aber leider keine Lösung gefunden. Gibt es hier in diesem Kreise jemand, der mir an der Stelle weiter helfen kann?

Vielen Dank schon mal im Voraus!

Gruss,
-jenzz-

Content-Key: 111227

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

Printed on: April 25, 2024 at 05:04 o'clock

Member: Biber
Biber Mar 12, 2009 at 11:45:49 (UTC)
Goto Top
Moin -jenzz-,


willkommen im Forum.
Für die Wahl eines geeigneten Werkzeugs wäre es noch sinnvoll zu wissen, welcher Art der Inhalt der Flatfiles sein mag (mit/ohne Umlauten, Sonderzeichen, Zeichencode), wie die Namens-Konventionen für die neue Gesamt-Datei sein sollen und ob/wie die Einzel-Import-Flatfiles nach erfolgreicher Transformation behandelt werden sollen.

Die Krönung und der heimliche Wunschtraum eines jeden Fricklers hier im Forum wären natürlich 3 oder 4 Beispieldatenzeilen...

Grüße
Biber
Member: bastla
bastla Mar 12, 2009 at 12:03:05 (UTC)
Goto Top
... und wenn Du dann auch noch das Geheimnis um "eine Information" im Dateinamen lüftest, sollte sich das per Batch (mit oder ohne VBScript-Unterstützung) machen lassen ...

Soll die ominöse "Information" übrigens tatsächlich in die einzelnen Dateien geschrieben werden, oder ev doch nur in den Zeilen der Gesamt-Datei aufscheinen?

Grüße
bastla

P.S.: Willkommen auch von mir ...
Member: -jenzz-
-jenzz- Mar 12, 2009 at 12:35:12 (UTC)
Goto Top
Hallo Biber, hallo Bastla.

Vielen Dank für den Willkommensgruß. Ich dachte mir schon, dass ihr zwei Euch dem annehmt. Ich habe schon viel von euch gelesen in diesem Forum. Und ehrlich gesagt, hatte ich gehofft, einen Rat von euch zu erhalten.

So, genug geschleimt, jetzt zum eigentlichen Problem. face-wink

Die Flatfiles sind in Unicode gehalten (also mit Umlauten, Sonderzeichen etc.) und sind im "Fixed width"-Format abgespeichert. Die neue Gesamtdatei soll im Prinzip jeden Datensatz der anderen Dateien enthalten, allerdings mit einem vorangestellten Teil aus dem jeweiligen Dateinamen. So ein Dateiname kann "TDWHre01.08-09-10" heißen, wobei nach dem Punkt das Lieferdatum steht. Der Teil re01 (heißt für jede Datei anders!) soll dann in jede Zeile der Datei eingefügt werden (vor den Datensatz oder dahinter ist egal, Hauptsache er ist drin). Falls das mit dem "delimited"-Statement zu schwierig ist, diese Information zu extrahieren, kann auch alles vor dem Punkt eingefügt werden und die Verarbeitungslogik im DWH-Prozess übernimmt das Abschneiden und Umformen. Die neue Gesamtdatei soll dann "TDWH.DAT" heißen.

Die originalen Datein sollen vor der Umwandlung in ein Archivverzeichnis kopiert werden. Das ist nicht weiter schwer. face-wink Nach einer erfolgreichen Verarbeitung aller Dateien (Bearbeiten und in neue Datei kopieren) können diese aus dem Originalverzeichnis gelöscht werden (auch kein Problem).

Zu erwähnen ist, dass solch simplen Befehle wie "xcopy" nicht funktionieren, d.h. ich arbeite mit dem "copy"-Befehl.

Um auf die Antwort von bastla zu reagieren: Die Verarbeitungslogik ist noch diskutierbar, allerdings soll dann in der Gesamtdatei die entsprechende Information in jeder Zeile hinterlegt sein. Es kommt nicht darauf an, dass diese Information auch in der originalen Datei hinterlegt wird. Ich dachte nur, dass dies einfacher wäre.

Ein kleines Beispiel:

Originaldatensatz aus der Datei TDWHre01.08-09-10 ("..." bedeutet, dass danach noch weitere Zeichen folgen, feste Anzahl an Zeichen in jeder Zeile):

TOS2120107110110000030009.09.2008 ...
TOS2120107110110000040009.09.2008 ...
TOS2120107110110000050009.09.2008 ...

In der Gesamtdatei soll es dann heißen:

re01TOS2120107110110000030009.09.2008 ...
re01TOS2120107110110000040009.09.2008 ...
re01TOS2120107110110000050009.09.2008 ...

Wobei wie gesagt sich das "re01" aus dem Namen der Datei ergibt und nicht zwingend vor der Zeile stehen muss. Es kann auch dahinter stehen (ist vielleicht sogar besser, damit sich die exakten Positionen der anderen Informationen nicht verändert).

Vielleicht ist das jetzt etwas deutlicher geworden, was ich machen möchte/muss. face-wink

Danke und Gruss,
-jenzz-
Member: bastla
bastla Mar 12, 2009 at 14:11:27 (UTC)
Goto Top
Hallo -jenzz-!

Wäre demnach die Vorschrift für den einzufügenden Text "Verwende vom Teil des Dateinames vor dem ersten Punkt alles nach den ersten 4 Stellen"?

Grüße
bastla
Member: -jenzz-
-jenzz- Mar 12, 2009 at 14:22:54 (UTC)
Goto Top
Hallo bastla.

Ja, so kann man das ausdrücken. face-smile Im Grundprinzip geht es mir darum, zu erfahren, wie man solche Operationen mit den normalen Hausmitteln macht und ob das überhaupt möglich ist. Laut einer Aussage hier im Forum soll dies ja möglich sein, ich habe nur absolut keinen blassen Schimmer, wie so etwas aussehen könnte. Denn sämtliche Threads hier beziehen sich auf erweiterte Funktionen, die mir leider nicht zur Verfügung stehen. face-sad

Gruss,
-jenzz-
Member: bastla
bastla Mar 12, 2009 at 18:42:03 (UTC)
Goto Top
Hallo -jenzz-!

Batch und Unicode ist keine sooo gute Kombination - daher etwas Unterstützung durch ein anderes "Hausmittel", nämlich VBScript:
@echo off & setlocal
set "Verz=D:\Flatfiles"  
set "Maske=TDWH*.*"  
set "Gesamt=D:\TDWH.DAT"  

set "AI=%temp%\AddInfo.vbs"  
> %AI% echo Set args=WScript.Arguments:Set fso=CreateObject("Scripting.FileSystemObject")  
>>%AI% echo Set FI=fso.OpenTextFile(args(0),,,True):Set FO=fso.OpenTextFile(args(1),8,True,True)
>>%AI% echo Do Until FI.AtEndOfStream:FO.WriteLine FI.ReadLine^&args(2):Loop:FO.Close:FI.Close

if exist "%Gesamt%" del "%Gesamt%"  
for %%i in ("%Verz%\%Maske%") do call :ProcessFile "%%i"  
::Ende des Hauptprogrammes
goto :eof

:ProcessFile
for /f "delims=." %%a in ("%~nx1") do set "DName=%%a"  
set "ReNr=%DName:~4%"  
cscript //nologo %AI% %1 "%Gesamt%" "%ReNr%"  
::ohne Unicode
::for /f "usebackq delims=" %%a in (%1) do >>"%Gesamt%" echo %%a %ReNr% 
goto :eof
Bitte die Pfade in den Zeilen 2 und 4 anpassen (wobei Zeile 2 nicht mit einem "\" enden darf, auch wenn es ein Root-Verzeichnis wäre - daher zB für "D:\" nur "D:" schreiben) ...

Das Löschen der Ausgangsdateien und ev weitere nach der Erzeugung der Gesamt-Datei anfallende Arbeitsschritte können im Batch unmittelbar vor der Zeile "::Ende des Hauptprogrammes" eingefügt werden.
Nur als Demo dabei ist in Zeile 21 der Batchcode, mit dem die Verarbeitung im einfachsten Fall (Ausgangsdateien nicht Unicode, keine Sonderzeichen "&<>|" oder eine ungerade Anzahl von Anführungszeichen enthalten ) erfolgen könnte - falls Du testen willst, einfach zwei Unicode-Dateien per
type D:\Flatfiles\Unicode-Datei>D:\FlatfilesASCII\ASCII-Datei
"umspeichern", die Doppelpunkte vor der Zeile 21 entfernen, die Zeile 19 ("cscript ...") durch vorangestellte "::" deaktivieren und den Batch auf die Dateien im Ordner "D:\FlatfilesASCII" loslassen (indem dieser in Zeile 2 eingetragen wird).
Noch eine Frage: Welche Dateigröße (Zeilenanzahl) erreichen eigentlich die einzelnen Ausgangsdateien?

Grüße
bastla
Member: -jenzz-
-jenzz- Mar 13, 2009 at 10:26:31 (UTC)
Goto Top
Hallo bastla,

ich bin beeindruckt. Das Skript funktioniert anstandslos. Die nötigen Zwischenschritte füge ich dann an den entsprechenden Stellen ein.

Die Dateien werden in der Regel 1-5MB groß, in Extremfällen bis zu 10MB. Die Anzahl der Dateien variiert zwischen 5 und 50 pro Tag.

Könnte das ein Problem darstellen?

Gruss,
-jenzz-
Member: bastla
bastla Mar 13, 2009 at 11:24:42 (UTC)
Goto Top
Hallo -jenzz-!

Kein Problem - ich war nur vorsichtshalber von sehr großen Dateien ausgegangen und verarbeite daher die Ausgangsdateien jeweils zeilenweise, anstatt sie gleich als Ganzes in den Speicher zu holen - der Performance-Unterschied würde aber vermutlich ohnehin nicht wirklich ins Gewicht fallen.

Grüße
bastla