Benutzer mit den meisten Antworten
Textdateien ohne Trennzeichen in csv verwandeln

Frage
-
Guten Abend,
bin noch am Lernen mit Powershell, hänge gerade an einer Anforderung fest.
Habe eine Testdatei mit >20000 Zeilen. Feste Spaltenbreiten.
Z.B. Name Firma Abteilung Raum Telefon
Wie kann ich die aufbereiten in eine CSV-Datei ?
Die zweite Datei finde ich noch schlimmer:
Firma Name Teilenummer Typ
Muster Meier, Hans 123456 PC
46465 BildschirmWieviele Zeilen es pro Person gibt, ist unterschiedlich. Manche haben nur eine Zeile, manche haben 15. Wie kann ich eine CSV-Datei erzeugen, die folgendes ausgibt:
Muster;Meier, Hans;123456;PC
Muster;Meier, Hans;46465;BildschirmAm Orignialformat kann ich nichts ändern, daher wollte ich es via Powershell aufbereiten.
Freue mich über Hinweise.
CU,
Axel
Antworten
-
Moin,
mit "von Tabelle zu Tabelle gleich" meinte ich natürlich "von Tabelle zu Tabelle derselben Art" ;-)
Feste Breite:
Sagen wir mal, Deine Spalten beginnen bei 1, 22, 44, 64 und 78. Dann sieht die primitive Lösung so aus:
$infile = "c:\temp\tab1.txt" $outfile = "c:\temp\tab1.csv" $lines = Get-Content $infile if (Test-Path $outfile ) { Remove-Item $outfile } foreach ($line in $lines) { $name = $line.Substring(0,21).Trim() $company = $line.Substring(21,22).Trim() $dept = $line.Substring(43,20).Trim() $room = $line.Substring(63,14).Trim() $phone = $line.Substring(77).Trim() $outline = "`"$name`",`"$company`",`"$dept`",`"$room`",`"$phone`"" $outline | Out-File $outfile -Append }
Natürlich kann man es noch verfeinern, z.B. in der Annahme, dass die Spaltenköpfe keine Leerzeichen enthalten, die Positionen aus der Kopfzeile auslesen, oder die Positionen zu Begin als Array oder Hashtable (dann inklusive Namen) zu hinterlegen.
Und nun mit mehrerern Detailzeilen pro Name + Company (Spaltenbreiten sind dieselben, nur halt eine weniger):
$infile = "c:\temp\tab2.txt" $outfile = "c:\temp\tab2.csv" $lines = Get-Content $infile if (Test-Path $outfile ) { Remove-Item $outfile } $name = "" $company = "" foreach ($line in $lines) { $xname = $line.Substring(0,21).Trim() $xcompany = $line.Substring(21,22).Trim() $part = $line.Substring(43,20).Trim() $type = $line.Substring(63).Trim() if ($xname -ne '') { $name = $xname } if ($xcompany -ne '') { $company = $xcompany } $outline = "`"$name`",`"$company`",`"$part`",`"$type`"" $outline | Out-File $outfile -Append }
Viel Spaß damit :-)
EDIT: Bei 20.000 Zeilen kann es sich durchaus lohnen, über effizienteres Lesen nachzudenken, hier am Beispiel des 2. Beispiels:
$infile = "c:\temp\tab2.txt" $outfile = "c:\temp\tab2.csv" #erst mal nur die Datei öffnen, noch nicht einlesen... $lines = [System.IO.File]::OpenText($infile) if (Test-Path $outfile ) { Remove-Item $outfile } $name = "" $company = "" #...und nun Zeile für Zeile einlesen, bis er $null einliest while ($null -ne ($line = $lines.ReadLine())) { $xname = $line.Substring(0,21).Trim() $xcompany = $line.Substring(21,22).Trim() $part = $line.Substring(43,20).Trim() $type = $line.Substring(63).Trim() if ($xname -ne '') { $name = $xname } if ($xcompany -ne '') { $company = $xcompany } $outline = "`"$name`",`"$company`",`"$part`",`"$type`"" $outline | Out-File $outfile -Append }
Evgenij Smirnov
msg services ag, Berlin -> http://www.msg-services.de
my personal blog (mostly German) -> http://it-pro-berlin.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.comIn theory, there is no difference between theory and practice. In practice, there is.
- Bearbeitet Evgenij Smirnov Mittwoch, 14. September 2016 21:19
- Als Antwort markiert Denniver ReiningMVP, Moderator Sonntag, 18. September 2016 21:20
Alle Antworten
-
Moin, ist es für eine regelmäßige Konvertierung gedacht und falls ja: Sind die Spaltenbreiten auch global fix, sprich: von Tabelle zu Tabelle gleich? Die zweite Herausforderung ist übrigens nicht schlimm: Du speicherst den ersten Teil weg, sobald er nicht leer ist, und bei der Ausgabe gibst Du immer den gespeicherten Wert aus...
Evgenij Smirnov
msg services ag, Berlin -> http://www.msg-services.de
my personal blog (mostly German) -> http://it-pro-berlin.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.comIn theory, there is no difference between theory and practice. In practice, there is.
-
Moin Moin,
ist als regelmäßige Konvertierung gedacht.
Die beiden Tabellen haben unterschiedlich breite Spalten, werde zwei Scripte erstellen.
Kannst Du mir einen Tipp geben, wie ich das mit dem "wegspeichern des ersten Teils" machen kann bzw. wie ich die festen Spaltenbreiten in Powershell hinterlege ?
Thx.
CU,
Axel
-
Moin,
mit "von Tabelle zu Tabelle gleich" meinte ich natürlich "von Tabelle zu Tabelle derselben Art" ;-)
Feste Breite:
Sagen wir mal, Deine Spalten beginnen bei 1, 22, 44, 64 und 78. Dann sieht die primitive Lösung so aus:
$infile = "c:\temp\tab1.txt" $outfile = "c:\temp\tab1.csv" $lines = Get-Content $infile if (Test-Path $outfile ) { Remove-Item $outfile } foreach ($line in $lines) { $name = $line.Substring(0,21).Trim() $company = $line.Substring(21,22).Trim() $dept = $line.Substring(43,20).Trim() $room = $line.Substring(63,14).Trim() $phone = $line.Substring(77).Trim() $outline = "`"$name`",`"$company`",`"$dept`",`"$room`",`"$phone`"" $outline | Out-File $outfile -Append }
Natürlich kann man es noch verfeinern, z.B. in der Annahme, dass die Spaltenköpfe keine Leerzeichen enthalten, die Positionen aus der Kopfzeile auslesen, oder die Positionen zu Begin als Array oder Hashtable (dann inklusive Namen) zu hinterlegen.
Und nun mit mehrerern Detailzeilen pro Name + Company (Spaltenbreiten sind dieselben, nur halt eine weniger):
$infile = "c:\temp\tab2.txt" $outfile = "c:\temp\tab2.csv" $lines = Get-Content $infile if (Test-Path $outfile ) { Remove-Item $outfile } $name = "" $company = "" foreach ($line in $lines) { $xname = $line.Substring(0,21).Trim() $xcompany = $line.Substring(21,22).Trim() $part = $line.Substring(43,20).Trim() $type = $line.Substring(63).Trim() if ($xname -ne '') { $name = $xname } if ($xcompany -ne '') { $company = $xcompany } $outline = "`"$name`",`"$company`",`"$part`",`"$type`"" $outline | Out-File $outfile -Append }
Viel Spaß damit :-)
EDIT: Bei 20.000 Zeilen kann es sich durchaus lohnen, über effizienteres Lesen nachzudenken, hier am Beispiel des 2. Beispiels:
$infile = "c:\temp\tab2.txt" $outfile = "c:\temp\tab2.csv" #erst mal nur die Datei öffnen, noch nicht einlesen... $lines = [System.IO.File]::OpenText($infile) if (Test-Path $outfile ) { Remove-Item $outfile } $name = "" $company = "" #...und nun Zeile für Zeile einlesen, bis er $null einliest while ($null -ne ($line = $lines.ReadLine())) { $xname = $line.Substring(0,21).Trim() $xcompany = $line.Substring(21,22).Trim() $part = $line.Substring(43,20).Trim() $type = $line.Substring(63).Trim() if ($xname -ne '') { $name = $xname } if ($xcompany -ne '') { $company = $xcompany } $outline = "`"$name`",`"$company`",`"$part`",`"$type`"" $outline | Out-File $outfile -Append }
Evgenij Smirnov
msg services ag, Berlin -> http://www.msg-services.de
my personal blog (mostly German) -> http://it-pro-berlin.de
Windows Server User Group, Berlin -> http://www.winsvr-berlin.de
Mark Minasi Technical Forum, reloaded -> http://newforum.minasi.comIn theory, there is no difference between theory and practice. In practice, there is.
- Bearbeitet Evgenij Smirnov Mittwoch, 14. September 2016 21:19
- Als Antwort markiert Denniver ReiningMVP, Moderator Sonntag, 18. September 2016 21:20