Price
20. Februar 2017 um 07:32
1
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
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
Price
20. Februar 2017 um 09:07
3
@hroptatyr vielen Dank für die schnelle Antwort
war geschockt wie schnell das ging
Könnten Sie mir vielleicht kurz weiter helfen, wo ich die quelle und Ziel-Datei(-pfand) angeben muss.
Bin noch Anfänger
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
Price
20. Februar 2017 um 09:28
5
wenn ich das wie u.a. aufbaue, dann ist die Datei zwar erstellt, aber leider leer
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 ...
Price
20. Februar 2017 um 11:02
7
@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.
Price
20. Februar 2017 um 12:18
9
@hroptatyr ich arbeite hauptsächlich mit Windows
habe aber auch einen Ubuntu Notebook um etwas über den Tellerrand zu schauen
by the way
leider geht es auch mit der Pipe nicht
Price
21. Februar 2017 um 07:58
10
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?
Price
21. Februar 2017 um 12:14
11
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}
Price
22. Februar 2017 um 07:09
12
so habs fertig gekriegt.
Das Script verarbeitet nun automatisch alle .csv-Dateien in das Zielformat.
Danke für die Unterstützung
# 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}
}