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

Skript für Template-Filegenerierung

Frage Entwicklung Batch & Shell

Mitglied: filippg

filippg (Level 3) - Jetzt verbinden

01.09.2010 um 20:51 Uhr, 3821 Aufrufe, 6 Kommentare

Suche Programm, dass aus einem Template und einer .csv für jede Zeile ein ausgefülltes Template erzeugt

Hallo,

ich suche etwas, das bestimmt irgendwer schon irgendwo im Internet gepostet hat, aber ich finde es nicht:
Ich habe ein Programm, das z.B. Nutzeranlagen als einzelne XML-Files entgegennimmt. Wenn ich nun eine Liste mit 20 Nutzeranlagen habe, muss ich 20 XML-Files erstellen, in denen ich jeweils nur den Name veränder. Das ist irgendwie umständlich, und muss doch auch einfacher gehen.
Ich suche also ein Skript mit folgender Funktionalität:
Übergeben werden zwei Dateien: Eine .csv mit beliebiger Spalten- und Zeilenzahl und ein Template. In dem Template sind Platzhalter entsprechend den Spaltennamen enthalten. Für jede Zeile erzeugt das Skript nun eine neue Datei, in der die Platzhalter mit den entsprechenden Spaltenwerten ersetzt werden.

Kann mir jemand bei der Suche weiterhelfen?

Danke

Filipp
Mitglied: bastla
01.09.2010 um 21:53 Uhr
Hallo filippg!

Wozu suchen - selber schreiben ...

... als VBS schematisch (und ungetestet) etwa so:
01.
CSV = "D:\Die.csv" 
02.
Delim = ";" 
03.
Template = "D:\Template.xml" 
04.
Pfad = "D:\Ausgabepfad XML-Dateien" 
05.
 
06.
Set fso = CreateObject("Scripting.FileSystemObject") 
07.
TemplateText = fso.OpenTextFile(Template).ReadAll 'Templateinhalt einlesen 
08.
Daten = Split(fso.OpenTextFile(CSV).ReadAll, vbCrLf) 'Daten aus CSV in Array einlesen 
09.
Felder = Split(Daten(0), Delim) 'Feldnamen = Platzhalter aus erster Zeile der CSV in  Array einlesen 
10.
 
11.
For i = 1 To UBound(Daten) 'alle Datensätze durchgehen 
12.
    Info = Split(Daten(i), Delim) 'Informationen aus den einzelnen Feldern des Datensatzes in Array einlesen 
13.
    XML = Pfad & "\" & Info(0) & ".xml" 'Dateiname aus erstem Feld übernehmen 
14.
    XMLText = TemplateText 'Originaltemplate als Ausgangspunkt 
15.
    For j = 0 To UBound(Info) 'alle Felder durchgehen 
16.
        XMLText = Replace(XMLText, Felder(j), Info(j)) 'anhand der Feldnamen die Platzhalter durch die eingelesenen Informationen erstezen 
17.
    Next 
18.
    fso.CreateTextFile(XML).Write XMLText 'Datei schreiben 
19.
Next
Vorausgesetzt wird, dass die Platzhalter als Feldnamen in der der ersten Zeile der CSV-Datei in der exakt gleichen Schreibweise stehen und es keine Fehler in der Struktur der Daten gibt.
Da ich keine Informationen über die Namen der Zieldateien hatte, wird einfach der Inhalt des jeweils ersten Feldes als Name verwendet ...

[Edit] Inzwischen oberflächlich getestet und einige Fehler korrigiert. [/Edit]

Grüße
bastla
Bitte warten ..
Mitglied: filippg
03.09.2010 um 19:28 Uhr
Hallo Bastla,

vielen Dank für dein Skript.
Es sind halt immer die Feinheiten, die das Skripten anstrengend machen - und ich hatte gehofft ein Skript zu finden, das diese Feinheiten schon enthält, so dass ich mich darum nicht selber kümmern muss. Z.B. wird das Skript nicht damit klarkommen, wenn das Delimiterzeichen in einem Feld enthalten ist. Hübsch wäre auch ein Skript, dass "vernünftig" reagiert, wenn die Ausgabedatei schon vorhanden ist, etc...
Aber scheinbar werde ich mir da wirklich gelegentlich mal ewtas selbst basteln müssen.... mal schauen, wann ich dazu komme, poste es dann hier.

Gruß

Filipp
Bitte warten ..
Mitglied: bastla
04.09.2010 um 22:06 Uhr
Hallo Filipp!

Mein Ansatz war ja nur als Grundgerüst gedacht - eine "vernünftige" Reaktion auf bereits vorhandene Ausgabedateien kann ja, wenn sie einmal definiert ist , nicht so schwer zu realisieren sein ...

Etwas kniffliger:
Z.B. wird das Skript nicht damit klarkommen, wenn das Delimiterzeichen in einem Feld enthalten ist.
Abgesehen davon, dass ja Du die CSV erstellst oder zumindest Einfluss darauf haben solltest und Dir wohl nicht selbst Knüppel zwischen die Beine werfen wirst, ließe sich auch das (vermutlich noch eleganter) lösen - zB als mit "cscript" zu startende Demo für eine Zeile:
01.
Zeile = """;Feld1"";Feld2;""Feld3;"";"""";""Feld 5"";""Feld 6 mit ; im Wert"";;;Feld 9" 
02.
Delim = ";" 
03.
 
04.
Auf = "{"   'beliebiges nicht in den Daten enthaltenes Zeichen 
05.
Zu = "}"    'anderes nicht in den Daten enthaltenes Zeichen 
06.
Dummy = "@" 'noch ein nicht in den Daten enthaltenes Zeichen 
07.
 
08.
WScript.Echo "Original   :" & Zeile 
09.
 
10.
'Unmittelbar aufeinander folgende Anführungszeichen kennzeichnen ein leeres Feld und ... 
11.
'... können daher vorweg durch "Nichts" ersetzt werden 
12.
Z = Replace(Zeile, """""", "") 
13.
WScript.Echo "Leer ohne "":" & Z 
14.
 
15.
Set rE = New RegExp 
16.
rE.Global = True 
17.
'Suche nach paarweisen Anführungszeichen ... 
18.
rE.Pattern = "("")([^""]*)("")" 
19.
'... und Ersetzen durch öffnende und schließende Klammern 
20.
Z = rE.Replace(Z, Auf & "$2" & Zu) 
21.
WScript.Echo "Geklammert :" & Z 
22.
 
23.
'Suche nach Vorkommen von Trennzeichen innerhalb der Klammern, zB {abc;xyz} und ... 
24.
 
25.
'Aufteilung:  (          $1         )     (   $2    )     (         $3        ) 
26.
rE.Pattern = "(" &Auf&"[^"&Delim&"]*)" & "("&Delim&")" & "([^"&Delim&"]*"&Zu&")" 
27.
'Ergebnis:             $1={abc               $2=;                 $3=xyz} 
28.
 
29.
'... Ersetzen des im Feld enthaltenen Trennzeichens = $2 durch einen "Dummy"-Wert ... 
30.
Z = rE.Replace(Z, "$1" & Dummy & "$3") 
31.
'... sowie Entfernung der umschließenden Klammern "{" und "}" 
32.
Z = Replace(Replace(Z, Auf, ""), Zu, "") 
33.
WScript.Echo "mit Dummy  :" & Z & vbCrLf 
34.
 
35.
'Zerlegung anhand des Trennzeichens in Felder 
36.
Felder = Split(Z, Delim) 
37.
For i = 0 To UBound(Felder) 'Durchlaufen der einzelnen Felder 
38.
    'Demo-Ausgabe mit Rückwandlung des "Dummy"-Wertes in das Trennzeichen 
39.
    WScript.Echo "Feld " & i + 1 & ": |" & Replace(Felder(i), Dummy, Delim) & "|" 
40.
Next
Vorausgesetzt habe ich, dass Felder, welche das Trennzeichen enthalten, auf jeden Fall unter Anführungszeichen stehen (ansonsten wäre ja eine Unterscheidung, noch dazu bei der gewünschten variablen Feldanzahl, gar nicht möglich). Zerlegt wird in dieser Demo die (mit ein paar "Spezialfällen" angereicherte) Zeile
";Feld1";Feld2;"Feld3;";"";"Feld 5";"Feld 6 mit ; im Wert";;;Feld 9
Grüße
bastla
Bitte warten ..
Mitglied: filippg
05.09.2010 um 03:35 Uhr
Hallo Bastla,

entschuldige, das waren beides nur als Beispiele gedacht. Das "Delimiter im Text"-Problem ergibt sich bei Powershell (die ich wohl nehmen werde) nicht, da die ein entsprechend sorgfältig implementiert ist. Und zur schon existierenden Ausgabedatei: klar, das lässt sich leicht abfangen. Aber das ist es eben: es sind zig Kleinigkeiten, an die man denken muss, wenn es wirklich gut sein soll. Und Kleinvieh macht auch Mist... Deswegen habe ich auch für ein solches eigentlich triviales Problem nach einer guten Fertiglösung gesucht...

Gruß

Filipp
Bitte warten ..
Mitglied: bastla
05.09.2010 um 11:18 Uhr
Hallo Filipp!
Deswegen habe ich auch für ein solches eigentlich triviales Problem nach einer guten Fertiglösung gesucht...
Dagegen habe ich ja auch gar nix einzuwenden - mir macht einfach nur das Scripten Spaß ...

Grüße
bastla
Bitte warten ..
Mitglied: filippg
26.10.2010 um 19:41 Uhr
Hallo,

ich hatte ganz vergessen hier zu posten, was ich jetzt verwende. Voilá:
01.
param( 
02.
[string]$Template, 
03.
[string]$csv 
04.
05.
$Description = " 
06.
Erwartet als ersten Parameter eine Template-Datei (beliebiges  
07.
Dateiformat), als zweiten eine .csv. Für jeden Datensatz in der 
08.
.csv wird das Template einmal ausgefüllt. Platzhalter, die in 
09.
## eingeschlossen sind werden durch den jeweiligen Spaltenwert 
10.
ersetzt. 
11.
Liegt im aktuellen Verzeichnis nur eine .csv-Datei, so muss 
12.
diese nicht mit angegeben werden. 
13.
Gibt es eine Spalte 'OutFile', so wird ihr Wert dem Ausgabe- 
14.
Dateiname angehängt. 
15.
(C) Filipp Geyer, 2010 
16.
17.
 
18.
if($Template -eq "") { 
19.
        Write-Host $Description 
20.
        break 
21.
22.
if($csv -eq ""){ 
23.
        $csvsInDir = Get-ChildItem "." -Filter "*.csv" 
24.
        if(($csvsInDir | Measure-Object).Count -eq 1) 
25.
                { $csv = $csvsInDir.FullName } 
26.
        else  
27.
                { Write-Host -ForegroundColor Red Es wurde keine Eingabedatei angegegeben, und es wurde keine oder mehr als eine .csv-Datei im Arbeitsverzeichnis gefunden; break} 
28.
29.
 
30.
if(-not(Test-Path -PathType Leaf $template)) 
31.
        {Write-Host -ForegroundColor Red Templatedatei $template konnte nicht gefunden werden; break } 
32.
$templateObj = Get-Item $Template 
33.
$templateBaseName = $templateObj.Name.Remove($templateObj.Name.Length - $templateObj.Extension.Length) 
34.
 
35.
if(-not(Test-Path -PathType Leaf $csv)) 
36.
        {Write-Host -ForegroundColor Red Eingabedatei $csv konnte nicht gefunden werden; break } 
37.
 
38.
$inFileObj = Get-Item $csv 
39.
if($inFileObj.Extension -ne ".csv") 
40.
        {Write-Host -ForegroundColor Red Eingabedatei $csv hat nicht die Endung .csv; break } 
41.
 
42.
function getNextFileName([string]$path, [string]$fileName, [string]$fileExt){ 
43.
        if(-not (Test-Path -PathType Container $path )){ 
44.
                Write-Host -ForegroundColor Red Ausgepfad $path existiert nicht! 
45.
                break 
46.
47.
        $currFileName = $path + "\" + $fileName  + $fileExt 
48.
         
49.
        for($i = 2; $i -lt 999; $i++){ 
50.
                if(-not (Test-Path -PathType Leaf $currFileName)){ 
51.
                        return $currFileName} 
52.
                $currFileName = $path + "\" + $fileName + "_" + $i + $fileExt    
53.
54.
        Write-Host -ForegroundColor Red Konnte keinen Dateinamen fuer die Ausgabe finden. 
55.
        break; 
56.
57.
 
58.
$dataset = Import-Csv $csv 
59.
$cols = $dataset | Get-Member -MemberType NoteProperty 
60.
$contTemplate = Get-Content $template 
61.
foreach($row in $dataset){ 
62.
        $currCont = $contTemplate 
63.
         
64.
        $outFile = getNextFileName $inFileObj.Directory.FullName ($templateBaseName + $row.OutFile) $templateObj.Extension 
65.
        foreach($col in $cols){  
66.
                $currCont = $currCont -replace ("##"+$col.Name+"##"), ($row.($col.Name)) 
67.
68.
         
69.
        $currCont > $outFile     
70.
}
Grüße

Filipp
Bitte warten ..
Ähnliche Inhalte
Apple
XCode Templates
Frage von Snowboarder1994Apple4 Kommentare

Hallo, um welche Kategorie handelt es sich hierbei bei xCode? Empty Application, Single View Application etc??? Wo ist denn ...

PHP
Joomla Template bearbieten
Frage von wescraven07PHP1 Kommentar

Moin Entwickler, ein Frage: Ich bin gerade dabei ein Joomla-Template für ein Mini-Projekt anzupassen. Ich benutze als Artikeleditor K2. ...

Windows Server
GPO Template für Java 8
Frage von Axel90Windows Server1 Kommentar

Hallo an alle, gibt es eine Möglichkeit, die Sicherheitseinstellungen von Java 8 über GPO zu konfigurieren? Speziell geht es ...

Debian
Postfix verschickt keine Bounce Templates
Frage von Black-ScorpionDebian4 Kommentare

Hallo, ich habe ein Problem mit einem Postfix Server. Ich versuche eine benutzerdefinierte Nachricht (Mail Delivery) zu hinterlegen. Das ...

Neue Wissensbeiträge
Apple

IOS 11.2.1 stopft HomeKit-Remote-Lücke

Tipp von BassFishFox vor 1 TagApple

Das Update für iPhone, iPad und Apple TV soll die Fernsteuerung von Smart-Home-Geräten wieder in vollem Umfang ermöglichen. Apple ...

Windows 10

Windows 10 v1709 EN murkst bei den Regionseinstellungen

Tipp von DerWoWusste vor 1 TagWindows 10

Dieser kurze Tipp richtet sich an den kleinen Personenkreis, der Win10 v1709 EN-US frisch installiert und dabei die englische ...

Webbrowser

Kein Ton bei Firefox Quantum über RDP

Tipp von Moddry vor 1 TagWebbrowser

Hallo Kollegen! Hatte das Problem, dass der neue Firefox bei mir auf der Kiste keinen Ton hat, wenn ich ...

Internet

EU-DSGVO: WHOIS soll weniger Informationen liefern

Information von sabines vor 1 TagInternet4 Kommentare

Wegen der europäische Datenschutzgrundverordnung stehen die Prozesse um die Registrierung von Domains auf dem Prüfstand. Sollte die Forderungen umgesetzt ...

Heiß diskutierte Inhalte
Windows Server
RODC kann nicht aus Domäne entfernt werden
Frage von NilsvLehnWindows Server18 Kommentare

HAllo, ich arbeite in einem Universitätsnetzwerk mit 3 Standorten. Die Standorte haben alle ein ESXi Cluster und auf diesen ...

Hardware
Kein Bild mit nur einer bestimmten Grafikkarten - Mainboard Konfiguration
gelöst Frage von bestelittHardware18 Kommentare

Hallo zusammen, ich hatte schon einmal eine ähnliche Frage gestellt. Damals hatte ich genau das gleiche Problem. Allerdings lies ...

Netzwerkmanagement
Mehrere Netzwerkadapter in einem PC zu einem Switch zusammenfügen
Frage von prodriveNetzwerkmanagement16 Kommentare

Hallo zusammen Vorweg, ich konnte schon einige IT-Probleme mit Hilfe dieses Forums lösen. Wirklich klasse hier! Doch für das ...

Hardware
Links klick bei Maus funktioniert nicht
gelöst Frage von Pablu23Hardware16 Kommentare

Hallo erstmal. Ich habe ein Problem mit meiner relativ alten maus jedoch denke ich nicht das es an der ...