denethor34
Goto Top

Multi CSV File Import Powershell

Hallo Zusammen,

ich komme gerade nicht weiter in meinen Powershell script

Ich möchte aus einer CSV Datei, in Powershell daten importieren.

Es sollen daten aus einer Tabelle importiert werden die nur ein gewissen wert entsprechen.

bsp:
Kunde;Nummer;Beschreibung
MusterCorp01;87654312;MusterCopretc01
MusterCorp02;27384628;MusterCorpetc02
MusterCorp03;23124238;MusterCorpetc03

So ist die CSV Datei aufgebaut.

Ich möchte aber nur den Kunde MusterCorp02 Filter, und dort dann nur die Nummer extrahieren.

Diese möchte ich dann weiter verwenden um mehrere CSV Files nach diese Nummer zu durchsuchen, und das Ergebnisse in Excel ausgeben.

Das ist der Grobe plan, ich scheitere aber schon am Anfang.

Wie ich die daten einlese in Powershell generell ist mir bekannt.

$Kunden = Import-Csv ".\Kunden.csv"  

Dann sind die Daten wie oben in der Powershell gespeichert. Oder ist dieser Anfang schon falsch ?

dann habe ich das noch versucht.

ForEach ($Nummer in $Kunden){
        if ($Kunden.Kunde -eq "MusterCorp02" ){  
            
        Write-Output $MusterCorp02.nummer
        }
    }

Dann gibt er mir aber alle nummern aller Kunden aus, und nicht die eine die ich möchte.

Vielleicht hat jemand eine Idee

Gruß

Content-Key: 665863

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

Printed on: April 19, 2024 at 10:04 o'clock

Member: TK1987
TK1987 Apr 19, 2021 updated at 06:12:20 (UTC)
Goto Top
Moin,

Zitat von @denethor34:
So ist die CSV Datei aufgebaut.
Wie ich die daten einlese in Powershell generell ist mir bekannt.

$Kunden = Import-Csv ".\Kunden.csv"  

Dann sind die Daten wie oben in der Powershell gespeichert. Oder ist dieser Anfang schon falsch ?
Fast. Du hast vergessen, dass Semikolon als Trennzeichen festzulegen
$Kunden = Import-Csv -Delimiter ';' ".\Kunden.csv"  

richtig wäre es so:
ForEach ($Nummer in $Kunden){
        if ($Nummer.Kunde -eq "MusterCorp02" ){  
            
        Write-Host $Nummer.Kunde
        }
    }

besser wäre in diesem Fall allerdings, deine Liste vorher mit Where-Object zu prüfen.
ForEach ($Nummer in ($Kunden | Where-Object Kunde -eq 'MusterCorp02'){  
  write-host $Nummer.Kunde
}
So durchlaufen deine anderen Einträge erst gar nicht mehr die Foreach-Schleife.

Gruß Thomas
Member: GarfieldBonn
GarfieldBonn Apr 19, 2021 updated at 06:51:01 (UTC)
Goto Top
$Kunden = Import-Csv "c:\temp\Kunden.csv" -Delimiter ";" | Where-Object Kunde -eq "MusterCorp02"  
write-Host $Kunden.Kunde, "   ", $Kunden.Nummer, "    ", $Kunden.Beschreibung  

Edit:
Da war Thomas schneller.
Gibt es mehr als einen Treffer muss der write-Befehl bei mir auch in eine Schleife ;) oder so als Out-GridView
 Import-Csv "c:\temp\Kunden.csv" -Delimiter ";" | Where-Object Kunde -eq "MusterCorp02" | ogv  
Member: denethor34
denethor34 Apr 19, 2021 at 07:06:11 (UTC)
Goto Top
Vielen Dank für die Rückmeldung.

Das hat nun soweit auch funktioniert mit beiden Ideen.

Nun ist noch die Frage wie ich die ausgelesenen Daten verwenden kann um mehrer CSV Files nach dieser Nummer zu durchsuchen.
Die CSV Files sind im Gleichen Schema aufgebaut.

ich dachte in die Richtung

$Kunden = Import-Csv ".\Kunden.csv" -Delimiter ";"  
$Daten = Import-Csv -Path (Get-ChildItem -Path "C:\work\*.csv") -Delimiter ";"  

ForEach ($Nummer in $Kunden| Where-Object Endkunde -eq "MusterCorp02"){  
       if ($MusterCorp02.Nummer in $Daten ) {
           Write-Host $MusterCorp02.Nummer 
       }
    }

Gruß
Member: TK1987
TK1987 Apr 19, 2021 updated at 07:52:56 (UTC)
Goto Top
Da würde ich gleich mit Select-String ran gehen.
Foreach ($Match in (Select-String '^MusterCorp02;' "C:\work\*.csv")) {  
  write-host "Kunde 'MusterCorp02' wurde gefunden in '$($Match.Filename)'"  
  $CSV = ConvertFrom-CSV -Input $Match.Line -d ';' -Header 'Kunde','Nummer','Beschreibung'  
  write-host Kundennummer: $CSV.Nummer
}
Member: GarfieldBonn
GarfieldBonn Apr 19, 2021 updated at 07:29:36 (UTC)
Goto Top
$files = gci c:\temp\*.csv
$Kundenliste =@()

foreach ($file in $Files) {
   $Kundenliste = $Kundenliste + @(Import-Csv $file -Delimiter ";" | Where-Object Kunde -eq "MusterCorp02")   
}

$Kundenliste | ogv
Member: denethor34
denethor34 Apr 19, 2021 at 14:17:16 (UTC)
Goto Top
Hallo Zusammen,

danke für die Rückmeldung.

Ich habe mir mal eine CSV Datei erstellt mit folgenden Inhalt.
Diese sind wiederum 4 mal erstellt mir unterschiedlichen Kosten

"Kunde","Kundennummer","Kosten"  
"MusterCorp01","46578372","99"  
"MusterCorp02","42134255","45"  
"MusterCorp03","12341522","76"  
"MusterCorp01","46578372","43"  
"MusterCorp02","42134255","75"  
"MusterCorp03","12341522","64"  
"MusterCorp01","46578372","21"  
"MusterCorp02","42134255","23"  
"MusterCorp03","12341522","42"  

$files = gci "C:\work\Files\*.csv"   
      $Kundenliste =@()
      
      foreach ($file in $Files) {
         $Kundenliste = $Kundenliste + @(Import-Csv $file -Delimiter "," | Where-Object Kunde -eq "MusterCorp02")   
      }
      $Kundenliste | Out-File C:\work\Files\MusterCorp02.txt

Ergebnis wäre

Kunde        Kundennummer Kosten
-----        ------------ ------
MusterCorp02 42134255     45    
MusterCorp02 42134255     78    
MusterCorp02 42134255     42    
MusterCorp02 42134255     45    
MusterCorp02 42134255     75    
MusterCorp02 42134255     23    
MusterCorp02 42134255     54    
MusterCorp02 42134255     43    
MusterCorp02 42134255     76    
MusterCorp02 42134255     45    
MusterCorp02 42134255     45    
MusterCorp02 42134255     23    

Was müsste ich nun machen, wenn ich MusterCorp03 mit zusätzlich in der Liste haben möchte ?
Die Anpassungen am Code in mit MusterCorp03 funktioniert nicht

$files = gci "C:\work\Files\*.csv" #gci = Get-ChildItem  
      $Kundenliste =@()
      
      foreach ($file in $Files) {
         $Kundenliste = $Kundenliste + @(Import-Csv $file -Delimiter "," | Where-Object Kunde -eq "MusterCorp02","MusterCorp03")   
      }
      $Kundenliste | Out-File C:\work\Files\MusterCorp.txt

Gruß
Member: TK1987
TK1987 Apr 19, 2021 updated at 14:28:44 (UTC)
Goto Top
foreach ($Match in (Select-String '^"?MusterCorp0[23]"?,' "C:\work\Files\*.csv")){  
  ConvertFrom-CSV -d ',' -Inp $Match.Line -Header 'Kunde','Kundennummer','Kosten'  
}
Member: GarfieldBonn
GarfieldBonn Apr 19, 2021 at 16:28:41 (UTC)
Goto Top
         $Kundenliste = $Kundenliste + @(Import-Csv $file -Delimiter "," | Where-Object {($_.Kunde -eq "MusterCorp02") -or ($_.Kunde -eq "MusterCorp03") })   
Member: denethor34
denethor34 Apr 19, 2021 at 19:42:15 (UTC)
Goto Top
Puh, danke für die Scripte,
kannst du mir sagen wie dieser String funktioniert Select-String '^"?MusterCorp0[23]"?,' "C:\work\Files\*.csv"
Was bedeuten die ^ und ? in der Zeile, wie auch die [23] ? der Rest ist mir soweit klar.

Script funktioniert soweit auch sehr gut, würde aber auch gerne verstehen was ich da ausführe.

Unter get-help select-string in der help finde ich nicht wirklich was dazu

Gruß
Member: denethor34
denethor34 Apr 19, 2021 at 19:43:45 (UTC)
Goto Top
Danke, der Script, funktioniert super danke.

Nun muss ich noch schauen das ich das Ergebnis wenn möglich in excel übergeben kann, für die ausrechnung, wenn jemand dazu ein tip hat, gerne her damit.
Member: TK1987
TK1987 Apr 19, 2021 updated at 21:31:06 (UTC)
Goto Top
Zitat von @denethor34:
kannst du mir sagen wie dieser String funktioniert
Das ist ein Regex-String.
Was bedeuten die ^ und ? in der Zeile, wie auch die [23] ? der Rest ist mir soweit klar.
  • ^ Bedeutet "Am Zeilenanfang"
  • ? Bedeutet, das Zeichen vor dem Fragezeichen kommt 0 oder 1 mal vor. Könnte man auch weglassen, wenn du in deiner CSV-Datei immer double quotes als Feldbegrenzer benutzen würdest. In deinem Eingangspost hattest du allerdings eine CSV-Datei ohne double quotes gepostet.
  • [23] ist eine Aufzählung von erlaubten Zeichen, hier also entweder 2 oder 3.

Um das noch besser zu verstehen:
Regex Tutorial
Regex Legende

EDIT:
Nun muss ich noch schauen das ich das Ergebnis wenn möglich in excel übergeben kann, für die ausrechnung, wenn jemand dazu ein tip hat, gerne her damit.
Ganz übersehen.
Ich nehme an, du willst auch die Excel-Formel mit Powershell einfügen? Solange du beim CSV-Format bleibst:
[Array]$CSV = Foreach ($Match in (Select-String '^"?MusterCorp0[23]"?,' "C:\work\Files\*.csv")){  
  ConvertFrom-CSV -d ',' -Inp $Match.Line -Header 'Kunde','Kundennummer','Kosten'  
}
$CSV += [pscustomobject]@{Kosten="=SUM(C2:C$($CSV.Count+1))"}  
$CSV | Export-Csv -NoTypeInformation -delimiter ';' -path "C:\Test\Datei.csv"  
Bei Excel ist übrigens, abweichend von @GarfieldBonn's Beitrag, zwingend Semikolon als Trennzeichen zu verwenden. Andernfalls hängen die gesamten Zeilen zusammen und müssen mit Excel erst manuell nachträglich getrennt werden.
Member: GarfieldBonn
GarfieldBonn Apr 19, 2021 at 20:40:36 (UTC)
Goto Top
Nun muss ich noch schauen das ich das Ergebnis wenn möglich in excel übergeben kann, für die ausrechnung, wenn jemand dazu ein tip hat, gerne her damit.

$Kudenliste | export-csv -Delimiter "," -path "C:\Pfad\Dateiname" -NoTypeInformation -Encoding UTF8  
Member: denethor34
denethor34 Apr 21, 2021 at 08:15:04 (UTC)
Goto Top
Super, soweit habe ich es verstanden und es funktioniert auch soweit ganz gut.
Danke für die unterstützung.

Gibt es auch eine möglichkeit zu sagen, das ich in der Sucher nach dem Kunde, auswählen kann aus einer liste ?

Sprich ich ersetze die "Select-String '^"?MusterCorp0[23]"?," mit einer Variable die ich in ein Fester auswählen kann ?
Wie z.b. promt etc.

oder ist sowas im Powershell festgelegt.
Ich dachte dort an der variable "ogv"

Ich würde das so einfach wie möglich umsetzen, das meine Kollegen nur auswählen müssen, welchen kunden Sie auslesen wollen.


Gruß