Batch - CSV Struktur Converter

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 :slight_smile:

Mit awk z.B.:

awk 'BEGIN{FS=";";OFS="|"}(!HEAD){print "HEAD",$1,$2;HEAD=1}{print "LINE",$3,$4,$5,$6; FOOT=$7}END{print "FOOT",FOOT}'

Macht aus:

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

das:

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

@hroptatyr vielen Dank für die schnelle Antwort :smile:
war geschockt wie schnell das ging :flushed:

Könnten Sie mir vielleicht kurz weiter helfen, wo ich die quelle und Ziel-Datei(-pfand) angeben muss.
Bin noch Anfänger :sweat_smile:

wenn ich das for /F gemacht hab, hatte ich die Möglichkeit direkt einen Quell- und Ziel-Pfand zu hinterlegen.
for /F „tokens=1,2,3,4,5 delims=;“ %%a in (C:\Projekt\Werkzeugkasten\TEST.csv)

Oh, das sieht nach Windows aus. Hm, also awk Eingaben kommen einfach hinten dran

awk 'SCRIPT' DATEI1 DATEI2 DATEI3

und die Ausgabe wird auf die Konsole geschrieben, so daß man eine Dateiumleitung braucht, unter Unix geht das mit > (vielleicht auch unter Windows?)

awk 'SCRIPT' EINGABE > AUSGABE

wenn ich das wie u.a. aufbaue, dann ist die Datei zwar erstellt, aber leider leer :frowning:
Ich glaube der Quell-Pfad muss doch etwas weiter oben erwähnt werden, oder?

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.CSV > C:\LernProjekt\ORDER_Neu.CSV

Ja, man muss natürlich auch den Pfad zu awk erwähnen:

c:\pfad\nach\awk ...

@hroptatyr danke für deine Tipps.
Leider mach irgendwas falsch.

$ 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

können Sie mir eine Seite oder ein Buch empfehlen.

ich will mir das ein bisschen aneignen.

Ja da fehlt noch ein Pipe:

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

Naja, awk kann man sich natürlich gut aneignen, allerdings ist das ein klassisches Unix-Tool. Da paßt Windows, was sich weder an die Original-Unix-Standards noch POSIX (der offene Unix-Standard) hält, nicht so recht ins Bild.

@hroptatyr ich arbeite hauptsächlich mit Windows
habe aber auch einen Ubuntu Notebook um etwas über den Tellerrand zu schauen :smiley:

by the way
leider geht es auch mit der Pipe nicht

das Problem ist anscheinend das Windows, dieses unterstützt einige Kommandos nicht aus bzw. kennt diese nicht.
cat krieg ich noch zum Laufen, aber awk funktioniert einfach nicht.
auch nicht mit Cygwin.
Jemand eine Idee, ob man das unter Windows zum Laufen kriegt oder muss ich dass in Powershell nachbauen?

ich hab das ganze nun mit Unterstützung in Powershell nachgebaut.
leider werden dann alle CSV-Dateien in eine Datei statt in separate geschrieben.
jemand eine Idee wo ich hier den Fehler mache?

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}

so habs fertig gekriegt.
Das Script verarbeitet nun automatisch alle .csv-Dateien in das Zielformat.
Danke für die Unterstützung :thumbsup:

# 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}
}