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
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 666868
Url: https://administrator.de/contentid/666868
Ausgedruckt am: 22.11.2024 um 07:11 Uhr
27 Kommentare
Neuester Kommentar
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
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
Ich hab mir deine letzten Beiträge mal angeschaut und ganz ehrlich, langsam solltest du wissen wie man ein Frage stellt.
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
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
Das ist jetzt aber schon deine dritte Frage in die Richtung ob etwas mit Powershell geht
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
Gruß
Doskias
Wenn du selber in der IT tätig bist, musst du Wissen wie breitgefächert alles sein kann 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
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
Gruß
Doskias
Schön, dass es geklappt hat. Mein Vorschlag wäre:
Anmerkung dazu: Die Werte K* und Co. stehen in der CSV-Datei in einem Feld mit dem Namen Werte.
Gruß
Doskias
$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
Zitat von @spongebob24:
Ok jetzt habe ich den Faden verolren
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.
Ok jetzt habe ich den Faden verolren
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. Wenn deine Überschrift in der CSV-Datei zum Beispiel Daten heißt, dann muss dort $Wert.Daten stehen.
Moin,
auch wenn es sich um eine CSV-Datei handelt, lässt sich die Aufgabenstellung leichter mit Get-Content lösen:
Gruß Thomas
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
Zitat von @TK1987:
Moin,
auch wenn es sich um eine CSV-Datei handelt, lässt sich die Aufgabenstellung leichter mit Get-Content lösen:
Gruß Thomas
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
2;Adminsitrator;www.administrator.de
Nummer;Website;URL
1;google;www.google.de
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
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 ...
...
Gern geschehen. Nicht vergessen die Hilfreichen Beiträge als Lösung zu markieren, damit es künftige Suchende leichter haben.
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.
Am besten öffnest du die CSV-Datei mal in einem Texteditor und postest hier einen Abschnitt davon im Codeblock.
Zitat von @spongebob24:
die Nummer steht immer an dieser Position und dahinter komm noch so einiges, kann ich hier leider nicht posten wegen Datenschutz
Du hättest die Daten ja verfälschen können, es geht ja schlicht ums Schema, nicht um die Richtigkeit der Daten.die Nummer steht immer an dieser Position und dahinter komm noch so einiges, kann ich hier leider nicht posten wegen Datenschutz
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++
}
}
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!
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:Wenn er bei dir nicht macht, stimmen deine Angaben nicht!
7699999998004 |
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.