spongebob24
Goto Top

Inhalt einer CSV Datei trennen mit Powershell?

Hi zusammen,

ich habe eine Frage. Ich habe in einem Ordner mehrere CSV Dateien liegen.
Deren Inhalt immer mehrere Zeilen hat, aber immer wieder mit den gleichen Buchstaben beginnt.

K*
A*
A*
A*
A*
P*
C*
L*

Also so beginnen die ganzen Sätze mit nachfolgend die Daten, die ich für die Übermittlungen benötige.

Nun, zum eigentlichen Thema, in einer Datei kommt es oft vor, das diese sich wieder holen, also erneut beim K Satz starten.
Wäre dies mit Powershell möglich, dann neue Dateien erstellen zu lassen, wo diese getrennt werden?

SG

Content-Key: 666868

Url: https://administrator.de/contentid/666868

Printed on: April 27, 2024 at 17:04 o'clock

Member: Doskias
Doskias May 19, 2021 at 06:29:01 (UTC)
Goto Top
Guten Morgen,

vielleicht kannst du deine Anfrage etwas präziser Stellen. Selbst nach mehrmaligen durchlesen verstehe ich nicht worauf du hinaus willst. Ich habe verstanden, dass du eine unbestimmte Anzahl von Dateien hast, und immer wenn in der Datei ein Datensatz mit K beginnt soll ab dort eine neue Datei erstellt werden. Ja das ist möglich. Nein den Code poste ich hier nicht, da es relativ einfach ist. Ich stell mir allerdings noch so banale Fragen wie: Was soll mit der Ursprungsdatei geschehen? Wie soll die neue Datei benannt werden? Was ist wenn es die neue Datei schon gibt? etc. Du lieferst kaum wirkliche Informationen, aber um deine Frage abschließend zu beantworten:
Ja es ist durchaus Möglich eine CSV-Datei zu splitten, wenn ein Kriterium erfüllt ist.

Gruß
Doskias
Member: spongebob24
spongebob24 May 19, 2021 at 06:37:02 (UTC)
Goto Top
Hi,

danke für deine schnelle Antwort.
Also die Ursprungsdatei darf gelöscht werden und es sollen einfach immer neue Dateien erstellt werden.
Inhalt was gesplittet werden soll ist immer beginn beim K* Satz und Endet beim L* Satz

Also Datei1 K* bis L* Satz
Datei2 K* bis L* Satz
Datei3 K* bis L* Satz

Neuer Dateiname ist komplett egal, nur die INhalte müssen gesplittet sein.
Duplikate sollte es nicht geben.

ich hoffe ich habe das nun Verständlich rüber gebracht.

SG
Member: Doskias
Doskias May 19, 2021 at 06:55:31 (UTC)
Goto Top
Ich hab mir deine letzten Beiträge mal angeschaut und ganz ehrlich, langsam solltest du wissen wie man ein Frage stellt.

ich hoffe ich habe das nun Verständlich rüber gebracht.
Nö. Erst heißt es immer wenn es mit K beginnt, jetzt heißt es von K bis L. Dann schreibst du Duplikate sollte es nicht geben, oben schreibst du aber:
in einer Datei kommt es oft vor, das diese sich wieder holen,
was denn jetzt? Wiederholen sich die Werte oder nicht? Wenn ja, dann gibt es auch Duplikate.

Deine Frage war ob es möglich ist. Die Antwort ist ja. in meinen Augen relativ einfach. Du brauchst nur import-csv und der Rest lässt sich mit einer Foreach Schleife und einer IF-Bedingung für Power-Shell-Beginner lösen. Das ist nur meine Meinung. Aus dem Bauch würde ich sagen, dass das sogar mit einem Ein- oder Zweizeiler möglich ist.

Wenn ich das hier Poste, dann würdest du erstens nichts daraus lernen und zweitens wirst du dafür bezahlt deinen Job zu machen nicht ich. ich helfe dir gerne wenn es irgendwo hakt und du in deinem PowerShell-Skript nicht weiter kommst. Das bedingt aber, dass du deinen Code hier einfach mal postest, den du schon hast.

Gruß
Doskias
Member: spongebob24
spongebob24 May 19, 2021 at 07:04:15 (UTC)
Goto Top
Hi,

also ich mache leider absolut 0 mit Powershell deshalb meine Frage.
Wenn du selber in der IT tätig bist, musst du Wissen wie breitgefächert alles sein kann face-wink und nicht andere Leute quasi als blöd hinstellen.

Diese Antwort von dir hat mir gereicht und ich werde mich da jetzt durchkämpfen vielen Dank.

Du brauchst nur import-csv und der Rest lässt sich mit einer Foreach Schleife und einer IF-Bedingung für Power-Shell-Beginner lösen.


SG
Member: Doskias
Doskias May 19, 2021 at 07:24:51 (UTC)
Goto Top
Zitat von @spongebob24:

Hi,

also ich mache leider absolut 0 mit Powershell deshalb meine Frage.
Das ist jetzt aber schon deine dritte Frage in die Richtung ob etwas mit Powershell geht face-wink

Wenn du selber in der IT tätig bist, musst du Wissen wie breitgefächert alles sein kann face-wink und nicht andere Leute quasi als blöd hinstellen.
Das ist richtig. Aber Powershell ist nichts neues. An Powershell führt(in meinen Augen) seit Jahren kein Weg mehr dran vorbei. Mittlerweile wir (zumindest bei uns) Powershell in den Berufsschulen unterrichtet, da es nunmal das Werkzeug von MS geworden ist. Früher war Batch Pflicht, heute ist es Powershell, wenn man Windows-Server administrieren will. Es war keineswegs meine Absicht dich als blöd hinzustellen. Wenn der Eindruck entstanden ist, dann entschuldige ich mich dafür.

Diese Antwort von dir hat mir gereicht und ich werde mich da jetzt durchkämpfen vielen Dank.
Du brauchst nur import-csv und der Rest lässt sich mit einer Foreach Schleife und einer IF-Bedingung für Power-Shell-Beginner lösen.
SG

So. Ich hab mir jetzt mal die "Mühe" gemacht und ein nicht verschachteltes Skript geschrieben, welches auch für PowerShell Beginner verständlich sein sollte. Ich bin auf 10 Zeilen Code gekommen, darunter schon 4 kosmetische. Befehle die ich benutzt habe in chronologischer Reihenfolge:

Import-CSV
foreach
if
export-csv
remove-item

Wenn du Code hast und dabei Hilfe brauchst, gibt's Hilfe face-wink

Gruß
Doskias
Member: spongebob24
spongebob24 May 19, 2021 at 07:27:48 (UTC)
Goto Top
Danke dir.
Sorry wenn Unverständlich erklärt,bei uns warens auch noch Batch Zeiten face-wink

SG
Member: spongebob24
spongebob24 May 19, 2021 at 11:09:36 (UTC)
Goto Top
Habe mir jetzt das alles Zusammengesucht und kann meine test.csv immer in 5 Zeilen aufteilen in neue CSV Dateien.
Werde dran bleiben damit ich immer ab dem Kopfsatz (K*) eine neue Datei mit dem INhalt erstellen kann.

Danke dir für die entscheidenden Hinweise.

# Read parent CSV
$InputFilename = Get-Content 'C:\Users\username\Desktop\subventory\test.csv'  
$OutputFilenamePattern = 'C:\Users\username\Desktop\subventory\test_done_'  
$LineLimit = 5

# Initialize
$line = 0
$i = 0
$file = 0
$start = 0

# Loop all text lines
while ($line -le $InputFilename.Length) {

    # Generate child CSVs
    if ($i -eq $LineLimit -Or $line -eq $InputFilename.Length) {
        $file++
        $Filename = "$OutputFilenamePattern$file.csv"  
        $InputFilename[$start..($line - 1)] | Out-File $Filename -Force
        $start = $line;
        $i = 0
        Write-Host "$Filename"  
    }

    # Increment counters
    $i++;
    $line++
}
Member: Doskias
Solution Doskias May 19, 2021 at 11:25:42 (UTC)
Goto Top
Schön, dass es geklappt hat. Mein Vorschlag wäre:

$datei=0
$CSV_File="C:\Temp\CSV\test.csv"  
$Basis=Import-Csv $CSV_File -Encoding Default
foreach ($Wert in $Basis)
{
if ($wert.werte -like "K*"){$datei++}  
$pfad="c:\temp\csv\"+$datei+".csv"  
export-csv -Path $pfad -InputObject $Wert -Append
}
Remove-Item $CSV_File -Force

Anmerkung dazu: Die Werte K* und Co. stehen in der CSV-Datei in einem Feld mit dem Namen Werte.

Gruß
Doskias
Member: spongebob24
spongebob24 May 19, 2021 at 11:33:04 (UTC)
Goto Top
So sieht meine CSV Datei aus.
Der Wert K* wiederholt sich mehrmals, und immer wenn dieser kommt will ich gerne eine neue CSV erstellen mit dem darunterliegenden Inhalt bis wieder K* kommt.

unbenannt
Member: Doskias
Doskias May 19, 2021 at 11:45:57 (UTC)
Goto Top
Ändere in
if ($wert.werte -like "K*"){$datei++}  

bei $wert.werte in $wert.deine_Überschrift und es sollte klappen.
Member: spongebob24
spongebob24 May 19, 2021 at 11:54:00 (UTC)
Goto Top
Ok jetzt habe ich den Faden verolren face-sad
Ich soll ja nur deinen Code nehmen und dann auf mich abändern Pfade etc. und dann sollte es Pro K* an neues File erstellen....

Ich bleibe dran danke.
Member: Doskias
Doskias May 19, 2021 at 12:06:06 (UTC)
Goto Top
Zitat von @spongebob24:

Ok jetzt habe ich den Faden verolren face-sad
Ich soll ja nur deinen Code nehmen und dann auf mich abändern Pfade etc. und dann sollte es Pro K* an neues File erstellen....

Ich bleibe dran danke.

ja fast. Du musst in Zeile 6 aber das Skript auf deine CSV-Datei anpassen. $wert.werte beinhaltet den Wert der Zeile, die in deiner CSV-Datei "Werte" heißt. Ja ich gebe es zu, ungünstiger Variablenname. face-wink Wenn deine Überschrift in der CSV-Datei zum Beispiel Daten heißt, dann muss dort $Wert.Daten stehen.
Member: spongebob24
spongebob24 May 19, 2021 at 12:18:05 (UTC)
Goto Top
Ok heute kein Hirn mehr dafür..............ich widme mich heute Sachen, die ich im Stegreif beherrsche....

THX derweilen
Member: TK1987
Solution TK1987 May 20, 2021 updated at 06:10:46 (UTC)
Goto Top
Moin,

auch wenn es sich um eine CSV-Datei handelt, lässt sich die Aufgabenstellung leichter mit Get-Content lösen:
$Ordner = 'D:\Pfad\zum\CSV-Ordner'  
Foreach ($File in (Get-ChildItem "$Ordner\*.csv")) {  
  $i = 1
  Foreach ($Section in ((Get-Content -Raw $File) -Split '\r?\n(?=K\*)')) {  
    $Section | Set-Content ("{0}\{1}_{2:d2}{3}" -f $File.DirectoryName, $File.Basename, $i, $File.Extension)  
    $i++
  }
}

Gruß Thomas
Member: spongebob24
spongebob24 May 20, 2021 at 06:17:17 (UTC)
Goto Top
Wow Cool danke.
Member: Doskias
Solution Doskias May 20, 2021 updated at 06:19:52 (UTC)
Goto Top
Zitat von @TK1987:

Moin,

auch wenn es sich um eine CSV-Datei handelt, lässt sich die Aufgabenstellung leichter mit Get-Content lösen:
$File = 'C:\Pfad\zur\Datei.csv'  
> $i = 1
> Foreach ($Section in ((Get-Content -Raw $File) -Split '\r?\n(?=K\*)')) {  
>   $Section | Set-Content ($File -replace '(?=\.csv$)',"_$($i.ToString('d2'))")  
>   $i++
> }

Gruß Thomas

Dann verlierst du doch aber bei den erstellten CSV-Dateien, die Überschrift. Je nachdem wie viele Werte die CSV-Datei hat würde ich das als extrem störend empfinden. Mit get-content wird da ja nicht Differenzziert. Zeileninhalt ist Zeileninhalt. Import-CSV hingegen nimmt die erste Zeile als Überschrift. Wenn die CSV-Datei zum Beispiel wie folgt aussieht:
Nummer;Website;URL
1;google;www.google.de
2;Adminsitrator;www.administrator.de

Dann kannst du das natürlich mit get-content auslesen. Dann hast du 3 Zeilen, wobei die erste nur die Überschriften enthält. Wenn ich aber ein import-csv nutze, dann habe ich 2 Spalten mit den entsprechenden Überschriften und kann im Skript mit $file.Website auf den Namen zugreifen und mit $file.URL auf die URL. Die Möglichkeit nimmst du dir mit get-content. Und wenn ich beide Websites in eigene Dateien Schreibe, dann habe ich bei get-content hinterher nur:
1;google;www.google.de
bzw.
2;Adminsitrator;www.administrator.de
Wenn du mit Import-csv und export-csv arbeitest, dann habe ich hinterher:
Nummer;Website;URL
1;google;www.google.de
und
Nummer;Website;URL
2;Adminsitrator;www.administrator.de

Mir gehen also die Überschriften nicht verloren, wodurch die weiterer Verarbeitung der CSV deutlich einfach ist.

Gruß
Doskias
Member: spongebob24
spongebob24 May 20, 2021 at 06:26:03 (UTC)
Goto Top
Guten Morgen,

für meinen Fall brauche ich die Überschriften nicht da die Files gleich durch meine EDI Schnittstelle rauschen.
7699999998004

Vielen Dank euch beiden ihr habt mir sehr geholfen.
Member: TK1987
TK1987 May 20, 2021 updated at 06:37:30 (UTC)
Goto Top
Zitat von @Doskias:
Dann verlierst du doch aber bei den erstellten CSV-Dateien, die Überschrift.
Auf dem geposteten Bild sind keine Überschriften zu erkennen, daher habe ich auch keine berücksichtigt - ansonsten liesse sich das aber auch leicht mit Überschriften lösen:
$Content = (Get-Content -Raw $File) -Split '(?<=^[^\r\n]+)[\r\n]+|\r?\n(?=K\*)'  
Foreach ($Section in $Content[1..($Content.count-1)]) {
  $Content,$Section | Set-Content ...
...
Member: Doskias
Doskias May 20, 2021 at 06:42:44 (UTC)
Goto Top
Zitat von @spongebob24:
Vielen Dank euch beiden ihr habt mir sehr geholfen.

Gern geschehen. Nicht vergessen die Hilfreichen Beiträge als Lösung zu markieren, damit es künftige Suchende leichter haben.
Member: TK1987
TK1987 May 20, 2021 at 06:45:03 (UTC)
Goto Top
Zitat von @spongebob24:
7699999998004
Steht die Nummer denn immer an der selben Position oder hält sie immer ein bestimmtes Format ein? Ist das das Zeilenende, oder folgt dahinter noch etwas?
Am besten öffnest du die CSV-Datei mal in einem Texteditor und postest hier einen Abschnitt davon im Codeblock.
Member: spongebob24
spongebob24 May 20, 2021 at 06:47:10 (UTC)
Goto Top
Hi,

die Nummer steht immer an dieser Position und dahinter komm noch so einiges, kann ich hier leider nicht posten wegen Datenschutz face-wink

SG
Member: spongebob24
spongebob24 May 20, 2021 at 06:47:21 (UTC)
Goto Top
Mach ich sofort.

SG
Member: TK1987
Solution TK1987 May 20, 2021 updated at 07:49:12 (UTC)
Goto Top
Zitat von @spongebob24:
die Nummer steht immer an dieser Position und dahinter komm noch so einiges, kann ich hier leider nicht posten wegen Datenschutz face-wink
Du hättest die Daten ja verfälschen können, es geht ja schlicht ums Schema, nicht um die Richtigkeit der Daten.

Versuch mal, ob es so funktioniert:
$Ordner = 'D:\Pfad\zum\CSV-Ordner'  
Foreach ($File in (Get-ChildItem "$Ordner\*.csv")) {  
  $i = 1
  Foreach ($AN in ((Get-Content -Raw $File) -Split '\r?\n(?=K\*)' | Group-Object @{e={$_.Split('|')[5]}})) {  
    $AN.Group | Set-Content ("{0}\{1}_{2:d2}{3}" -f $File.DirectoryName, $File.Basename, $i, $File.Extension)  
    $i++
  }
}
Member: spongebob24
spongebob24 May 20, 2021 at 08:03:11 (UTC)
Goto Top
Stimmt ja kann ich verfälschen.

Mit dem Script macht es gar nichts.

SG
Member: TK1987
TK1987 May 20, 2021 updated at 08:34:57 (UTC)
Goto Top
Zitat von @spongebob24:
Mit dem Script macht es gar nichts.
Und genau das mein ich. Ich kann hier nur versuchen, mir anhand deiner bisher sperrlich geposteten Dateischnipsel eine Beispieldatei zu bauen - mit dieser funktioniert das ganz Wunderbar.

Wenn er bei dir nicht macht, stimmen deine Angaben nicht!
7699999998004
die Nummer steht immer an dieser Position
Wenn ich die 'k*' Zeile an der Pipe zerlege, müsste sonst das Element mit dem Index 5 die Artikelnummer sein:
unbenannt

Also habe ich alle Objekte zusammengefasst, bei denen der Index 5 übereinstimmt:
... | Group-Object @{e={ $_.Split('|')[5] }} ...  

Ohne zu wissen, wie deine Daten genau aufgebaut sind, können wir hier nur rätselraten.
Member: spongebob24
spongebob24 May 20, 2021 at 08:40:18 (UTC)
Goto Top
Hi,

so sehen die Zeilen aus, allerdings nicht immer gleich lang.

76999999980041546802|91259387|1000514133|10.05.2021|11.05.2021|11.30|11.05.2021|09.00|508566001|0|08.05.2021|2|1|10|6|0,6|kundenname

Um die Fett gedruckte Nummer geht es, ist die dieselbe, sollte nicht getrennt werden.

SG
Member: spongebob24
spongebob24 May 26, 2021 at 07:15:51 (UTC)
Goto Top
Danke dir klappt nun perfekt.

SG