Batch - CSV Strucktur Converter


warface

Mitglied
Hey Leute,

ich benötige einen kleinen Tipp und zwar möchte ich eine CSV via Batch neu konvetieren.
Die CSV-Datei sieht wie folgt aus

Aufbau:
Auftragsnummer;Auftragsdatum;Artikelnummer;Bezeichnung;Menge;Preis;Porto.

und ich würde die Datei gerne in das folgende Format umwandeln

Zielformat

HEAD|Auftragsnummer|Auftragsdatum|
LINE| Artikelnummer|Bezeichnung|Menge|Preis
FOOT|Porto

Bespiel:
Vorher

201711;2017-02-17;Ai7P;Apple iPhone 7 Plus;1;799,00;6,99
201711;2017-02-17;Ai7;Apple iPhone 7;1;699,00;6,99

Nachher
HEAD|201711|2017-02-17
LINE| Ai7P | Apple iPhone 7 Plus |1|799,00
LINE| Ai7 | Apple iPhone 7 |1|699,00
FOOT|6,99

ich weiß wie man das ganze ausliest und schreibt, mein Problem ist das group by und die Fußzeile.

danke schon mal für die Vorschläge :)
 

HonniCilest

Erfahrenes Mitglied
Brrrr da wird mir ganz kalt.

1) Das ist keine 5min-Aufgabe, niemand wird dir einen fertigen Code vorsetzen. Daher bitte anfangen und aufzeigen wo deine Probleme liegen.
2) Und du willst das wirklich unbedingt mit Batch machen? Ich kann mir nichts Schrecklicheres an der Stelle vorstellen. Alternative: Powershell?
3) Was passiert, wenn ein FOOT sich weiterhin differenziert, ist es dann HEAD LINE FOOT LINE FOOT?
4) Wofür ist dieses Format zwingend notwendig? Könnte man nicht einfach eine Mehrfachsortierung vornehmen? ^^
 

warface

Mitglied
Hallo HonniCilest,
1.)
ich bin mit etwas Unterstützung schon weiter gekommen, leider hab ich da irgendwo einen Fehler
cat C:\LernProjekt\ORDER.csv | awk 'BEGIN{FS=";";OFS="|"}(!HEAD){print "HEAD",$1,$2;HEAD=1}{print "LINE",$3,$4,$5,$6; FOOT=$7}END{print "FOOT",FOOT}' > C:\LernProjekt\ORDER_Neu.CSV

2.) ich würde es gerne automatisiert über eine Batch machen, meinst du mit Powershell wäre es einfacher?
3.) Die Datei beinhaltet immer nur ein Header und ein Foot
4.) Ich brauche dieses Zielformat für ein Tool
 

warface

Mitglied
Ich bin nun dahinter gekommen was das Problem ist.
Windows kann mit awk nichts anfangen.
Cat funktioniert, weil ich mal eine Erweiterung eingespielt hab, damit UNIX befehle funktionieren.
werde wohl auf PowerShell wechseln müssen.
Ist ein Umsetzung in PowerShell sehr umständlich?
 

HonniCilest

Erfahrenes Mitglied
Nö. Die Rahmenbedingungen, die du genannt hast, machen es sogar noch einfacher, ich dachte vorher man müsste den Inhalt auch noch nach HEAD zusammenfassen, sortieren und so.

Unter den genannten Bedingungen habe ich dir schnell etwas zusammengebastelt.

Code:
# INITIALIZE
$head = ""
$lines = @()
$foot = ""
# READ
Import-Csv -Path C:\tutorials\tutorials.csv -Delimiter ';' | %{
    # HEAD
    if ($head -eq "") {
        $head = 'HEAD', $_.Auftragsnummer, $_.Auftragsdatum -join '|'
    }
    # FOOT
    if ($foot -eq "") {
        $foot = 'FOOT', $_.Porto -join '|'
    }
    # LINE
    $line = 'LINE', $_.Artikelnummer, $_.Bezeichnung, $_.Menge, $_.Preis -join '|'
    $lines += $line
}
# WRITE
$target = C:\tutorials\tutorials.txt
Out-File -FilePath $target -InputObject $head
$lines | %{
    Out-File -FilePath $target -Append -InputObject $_
}
Out-File -FilePath $target -Append -InputObject $foot
 
Zuletzt bearbeitet:

warface

Mitglied
@HonniCilest erst einmal vielen Dank für die Arbeit :-D
leider ist die Output-Datei leer.
Ich hab mir mal den Quellcode, den du erstellt hast angeschaut.
wo genau deklarierst du welche spalte welche Variable ist?
 

warface

Mitglied
@HonniCilest jetzt hab ich es verstanden du gehst davon aus, dass die Spaltenüberschriften vorhanden sind :)

Vielen Dank hast mir echt Super weitergeholfen ;)

will das ganze nun noch automatisiert machen
poste es dann hier wenn ich fertig bin :)
 
Zuletzt bearbeitet:

warface

Mitglied
Ich hab das ganze noch etwas nach meinen Bedürfnissen angepasst,
leider komme ich nicht drauf wie ich das ganze bei mehreren Dateien ausführen kann :(
wenn ich das mit allen csv-Dateien aus einem Verzeichnis mache werden diese in eine Datei eingefügt.
sieht hier jemand vielleicht den Fehler?

# INITIALIZE
$file = Get-ChildItem "C:\lernProjekt\*.csv"
foreach($str in $files)
{$content = get-content -path $str.versionInfo.Filename
$filename = ""
$info = ""
$head = ""
$lines = @()
$foot = ""
# READ
Import-Csv -Path $file -Delimiter ';' | %{
# Filename
if ($filename -eq "") {
$filename= "ORDER", $_.Auftragsnummer -join "_"
}
# INFO
if ($info -eq "") {
$info = 'INFO', $_.Auftragsnummer -join '|'
}
# HEAD
if ($head -eq "") {
$head = 'HEAD', $_.Auftragsdatum -join '|'
}
# FOOT
if ($foot -eq "") {
$foot = 'FOOT', $_.Porto -join '|'
}
# LINE
$line = 'LINE', $_.Artikelnummer, $_.Bezeichnung, $_.Menge, $_.Preis -join '|'
$lines += $line

# WRITE

$target = "C:\LernProjekt\verarbeitet\$filename.txt"
Out-File -FilePath $target -InputObject $info, $head
$lines | %{
Out-File -FilePath $target -Append -InputObject $_
}
Out-File -FilePath $target -Append -InputObject $foot}
$content | set-content $str}
 

warface

Mitglied
habs hingekriegt, das PowerShell-Skript verarbeitet nun alle CSV-Dateien in das gewünschte Zielformat.
Danke für die Unterstützung. ;)
Code:
# INITIALIZE
ForEach ($file in Get-ChildItem  C:\LernProjekt\*.csv)
{
$file.name

$filename = ""
$info = ""
$head = ""
$lines = @()
$foot = ""
# READ
Import-Csv -Path $file -Delimiter ';' | %{
# Filename
if ($filename -eq "") {
$filename= "ORDER", $_.Auftragsnummer -join "_" 
}
# INFO
if ($info -eq "") {
$info = 'INFO', $_.Auftragsnummer -join '|' 
}
# HEAD
if ($head -eq "") {
$head = 'HEAD', $_.Auftragsdatum -join '|'
}
# FOOT
if ($foot -eq "") {
$foot = 'FOOT', $_.Porto -join '|'
}
# LINE
$line = 'LINE', $_.Artikelnummer, $_.Bezeichnung, $_.Menge, $_.Preis -join '|'
$lines += $line

# WRITE

$target = "C:\LernProjekt\verarbeitet\$filename.txt"
Out-File -FilePath $target -InputObject $info, $head
$lines | %{
Out-File -FilePath $target -Append -InputObject $_
}
Out-File -FilePath $target -Append -InputObject $foot}
}
 
Zuletzt bearbeitet von einem Moderator:

HonniCilest

Erfahrenes Mitglied
Ich freue mich, dass du dein Ziel erreicht hast. Ich habe mit Absicht zwischenzeitlich nicht geantwortet, denn wie man sieht hast du alles ohne weitere Hilfe durch mich lösen können. Du hast bestimmt etwas daraus gelernt, scheint mir zumidnest so :)

Magst du ggf. deinen Code noch in entsprechende Tags zusammenfassen? [ CODE=Powershell]Code[ /CODE]
(aber ohne die Leerzeichen in den Tags)
 

warface

Mitglied
@HonniCilest
das Thread ist zwar schon geschlossen, aber vielleicht kannst du mir weiterhelfen.
wie kann ich den Quellcode am einfachsten umstellen, damit ich eine Gruppierung nach INFO und HEAD hab?

ich habe nun Dateien die mehrere Heads und Positionen haben und krieg die Gruppierung nicht richtig hin.

Vielen Dank im voraus.
 

HonniCilest

Erfahrenes Mitglied
Dann darfst du innerhalb der Schleife nicht gleich schreiben, sondern müsstest erst alles speichern, dann sortierten und die sortierte Liste schreiben.
Oder erst in eine temp Datei schreiben und diese dann umschreiben in das eigentliche Gruppierte Ergebnis
 

HonniCilest

Erfahrenes Mitglied
Wenn du alles erstmal speicherst könnte das so aussehen:
Code:
$objectList = @()

$objectList += [pscustomobject]@{info='A'; head='HEAD1'; lines=@(); foot='FOOT1'}
$objectList += [pscustomobject]@{info='C'; head='HEAD3'; lines=@(); foot='FOOT3'}
$objectList += [pscustomobject]@{info='B'; head='HEAD2'; lines=@(); foot='FOOT2'}
$objectList += [pscustomobject]@{info='A'; head='HEAD2'; lines=@(); foot='FOOT2'}

$objectList | Group-Object {$_.info}

Könnte aber bei zu großen Datenmengen irgendwann blöd sein und dir den Speicher zuhauen.
 

Neue Beiträge