gravelking
Goto Top

Powershell Zeichen ersetzen

Hallo zusammen,

ich komme bei einer Aufgabenstellung nicht weiter.

Und zwar muss ich in einem Textfile vergleichen, ob es doppelte Artikel gibt, und wenn ja nur die Artikel mit dem niedrigeren Artikelindex in ein neues Textfile ausgeben.
Das funktioniert auch soweit. Ich scheitere aber daran, das im Ausgabefile dann für den Status des Artikels eine 1 gesetzt
werden soll.

Hier mal der Aufbau des EingabeFiles:

Artikelnummer;Artikelbezeichnung;Artikelindex;Artikelgruppe;Liefereinheit;Status;Zusatzbezeichnung;Zeichnungsnummer;Zeichnungsindex;Kundenartikelnummer;
0815;Beispiel;2;TDM;STUECK;0;;;;0
0815;Beispiel;3;TDM;STUECK;0;;;;0

Das Ausgabefile sollte dann so aussehen:

Artikelnummer;Artikelbezeichnung;Artikelindex;Artikelgruppe;Liefereinheit;Status;Zusatzbezeichnung;Zeichnungsnummer;Zeichnungsindex;Kundenartikelnummer;
0815;Beispiel;2;TDM;STUECK;1;;;;0

Allerdings bekomme ich es nicht hin, die 1 zu setzen.

Hier mal mein bisheriges Script:

# Pfade zu den Eingabe- und Ausgabetextdateien
$eingabeDatei = "D:\ToDo\alt.txt"  
$ausgabeDatei = "D:\ToDo\neu.txt"  

# Hashtable zum Speichern der Artikelnummern und ihrer Indizes
$geseheneArtikelnummern = @{}

# Lese die Eingabedatei zeilenweise
Get-Content $eingabeDatei | ForEach-Object {
    $aktuelleZeile = $_
    $artikelnummer = ($aktuelleZeile -split ";")[0]  
    $index = ($aktuelleZeile -split ";")[2].Trim() # Entferne führende und folgende Leerzeichen  

    # Überprüfe, ob die Artikelnummer bereits vorhanden ist
    if ($geseheneArtikelnummern.ContainsKey($artikelnummer)) {
        # Finde den Index der Zeile mit der bereits vorhandenen Artikelnummer
        $indexBereitsVorhanden = $geseheneArtikelnummern[$artikelnummer]

        # Überprüfe, ob der Index der aktuellen Zeile kleiner ist (numerischer Vergleich)
        if ([int]$index -lt [int]$indexBereitsVorhanden) {
            # Ändere den Status auf 1 und schreibe die Zeile in die Ausgabedatei
            $aktuelleZeile -replace "^((?:[^;]+;){5})", "`$1" + "1;" | Add-Content -Path $ausgabeDatei  
        }
    } else {
        # Füge die Artikelnummer mit dem Index der Zeile der Hashtable hinzu
        $geseheneArtikelnummern.Add($artikelnummer, $index)
        # Schreibe die Zeile in die Ausgabedatei
        $aktuelleZeile | Add-Content -Path $ausgabeDatei
    }
}

Wäre super, wenn mich jemand aufschlauen könnte, wo mein Problem liegt.

Grüße

Content-ID: 7978605854

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

Ausgedruckt am: 12.11.2024 um 19:11 Uhr

7907292512
7907292512 28.07.2023 aktualisiert um 10:51:52 Uhr
Goto Top
Moin
Geht viel einfacher und cleaner mit Group-Object und Import-CSV

Wenn die CSV Überschriften hat dann so
$eingabeDatei = "D:\ToDo\alt.txt"    
$ausgabeDatei = "D:\ToDo\neu.txt"  

$csv = Import-CSV $eingabedatei -Delimiter ";"  
$csv | sort {[int]$_.Artikelindex} | group-object Artikelnummer | %{
    if ($_.Count -gt 1){
        $_.Group[0].Status = 1
    }
    $_.Group[0]
} | export-csv $ausgabedatei -Delimiter ";" -NoTypeInformation -Encoding UTF8  
tio.run (Sample)

Wenn keine Überschriften vorhanden sind dann
$eingabeDatei = "D:\ToDo\alt.txt"        
$ausgabeDatei = "D:\ToDo\neu.txt"      

$csv = Import-CSV $eingabedatei -Delimiter ";"  -Header 'Artikelnummer','Artikelbezeichnung','Artikelindex','Artikelgruppe','Liefereinheit','Status','Zusatzbezeichnung','Zeichnungsnummer','Zeichnungsindex','Kundenartikelnummer'    
$csv | sort {[int]$_.Artikelindex} | group-object Artikelnummer | %{
    if ($_.Count -gt 1){
        $_.Group[0].Status = 1
    }
    $_.Group[0]
} | export-csv $ausgabedatei -Delimiter ";" -NoTypeInformation -Encoding UTF8  

tio.run (sample)

Gruß siddius

/edit/ fehlende Klammer behoben
mayho33
mayho33 28.07.2023 um 11:04:06 Uhr
Goto Top
Zitat von @7907292512:

Moin
Geht viel einfacher und cleaner mit
$eingabeDatei = "D:\ToDo\alt.txt"    
$ausgabeDatei = "D:\ToDo\neu.txt"  

$csv = Import-CSV $eingabedatei -Delimiter ";"  
$csv | sort {[int]$_.Artikelindex} | group-object Artikelnummer | %{
    if ($_.Count -gt 1){
        $_.Group[0].Status = 1
    }
    $_.Group[0]
} | export-csv $ausgabedatei -Delimiter ";" -NoTypeInformation -Encoding UTF8  

Ja, nein! Im Beispiel gibt der TO eine CSV an die gleiche Elemente enthält. Import-CSV kann nicht umgehen damit face-wink Quasi wie Hashes und gleicher ID. Ansonsten gebe ich dir vollkommen recht!
error


Grüße!
7907292512
7907292512 28.07.2023 aktualisiert um 11:18:10 Uhr
Goto Top
Zitat von @mayho33:
Ja, nein! Im Beispiel gibt der TO eine CSV an die gleiche Elemente enthält. Import-CSV kann nicht umgehen damit face-wink Quasi wie Hashes und gleicher ID. Ansonsten gebe ich dir vollkommen recht!

Na sicher! Laut dem TO hat das Teil hat eindeutige Überschriften in der Quelldatei, ist dann also kein Problem:
Hier mal der Aufbau des EingabeFiles:
Artikelnummer;Artikelbezeichnung;Artikelindex;Artikelgruppe;Liefereinheit;Status;Zusatzbezeichnung;Zeichnungsnummer;Zeichnungsindex;Kundenartikelnummer
0815;Beispiel;2;TDM;STUECK;0;;;;0
0815;Beispiel;3;TDM;STUECK;0;;;;0

Wenn sie dagegen keine Überschriften hätte, ist das auch kein Beinbruch, dann gibt man sie eben explizit an face-wink:
$eingabeDatei = "D:\ToDo\alt.txt"      
$ausgabeDatei = "D:\ToDo\neu.txt"    

$csv = Import-CSV $eingabedatei -Delimiter ";"  -Header 'Artikelnummer','Artikelbezeichnung','Artikelindex','Artikelgruppe','Liefereinheit','Status','Zusatzbezeichnung','Zeichnungsnummer','Zeichnungsindex','Kundenartikelnummer'  
$csv | sort {[int]$_.Artikelindex} | group-object Artikelnummer | %{
    if ($_.Count -gt 1){
        $_.Group[0].Status = 1
    }
    $_.Group[0]
} | export-csv $ausgabedatei -Delimiter ";" -NoTypeInformation -Encoding UTF8    

DEMO

Works as designed!
gravelking
gravelking 28.07.2023 um 11:29:49 Uhr
Goto Top
Ihr seit der Hammer, das ist tatsächlich sehr viel einfacher als mein Versuch.

Aber warum sind jetzt in der Ausgabe-Datei lauter Quotation marks ?

"Artikelnummer";"Artikelbezeichnung";"Artikelindex";"Artikelgruppe";"Liefereinheit";"Status";"Zusatzbezeichnung";"Zeichnungsnummer";"Zeichnungsindex";"Kundenartikelnummer"
"0815";"Beispiel";"2";"TDM";"STUECK";"1";"";"";"";"0"

Bekommt man die auch noch weg ?
mayho33
mayho33 28.07.2023 um 11:30:26 Uhr
Goto Top
Zitat von @7907292512:
Na sicher! Laut dem TO hat das Teil hat eindeutige Überschriften in der Quelldatei, ist dann also kein Problem:
Hier mal der Aufbau des EingabeFiles:
Artikelnummer;Artikelbezeichnung;Artikelindex;Artikelgruppe;Liefereinheit;Status;Zusatzbezeichnung;Zeichnungsnummer;Zeichnungsindex;Kundenartikelnummer
0815;Beispiel;2;TDM;STUECK;0;;;;0
0815;Beispiel;3;TDM;STUECK;0;;;;0

HUCH!!! Ja hat er! DAs habe ich voll übersehen 🤦‍♂️😂 Sorry wegen der Falschmeldung! Bin im Urlaub! Da arbeitet alles auf 1/4 Kraft 🤷‍♂️
7907292512
Lösung 7907292512 28.07.2023 aktualisiert um 11:44:08 Uhr
Goto Top
Zitat von @gravelking:

Ihr seit der Hammer, das ist tatsächlich sehr viel einfacher als mein Versuch.

Aber warum sind jetzt in der Ausgabe-Datei lauter Quotation marks ?I
Ist Standard bei MS, hat gute Gründe wenn der Delimiter im Text vorkommen kann.

"Artikelnummer";"Artikelbezeichnung";"Artikelindex";"Artikelgruppe";"Liefereinheit";"Status";"Zusatzbezeichnung";"Zeichnungsnummer";"Zeichnungsindex";"Kundenartikelnummer"
"0815";"Beispiel";"2";"TDM";"STUECK";"1";"";"";"";"0"

Bekommt man die auch noch weg ?

Klar kein Problem, für das erste Beispiel mit vorhandenen Spaltenüberschriften in der Quelldatei so:
$eingabeDatei = "D:\ToDo\alt.txt"      
$ausgabeDatei = "D:\ToDo\neu.txt"    

$csv = Import-CSV $eingabedatei -Delimiter ";"    
($csv | sort {[int]$_.Artikelindex} | group-object Artikelnummer | %{
    if ($_.Count -gt 1){
        $_.Group[0].Status = 1
    }
    $_.Group[0]
} | convertto-csv -Delimiter ";" -NoTypeInformation) -replace '"' | set-content $ausgabedatei -Encoding UTF8  

tio.run (sample)

Wenn man schon Powershell Version 7 verwendet hat Export-CSV auch schon einen Parameter dafür: -UseQuotes Never, dann entfällt dieser Workaround für das Entfernen der Anführungszeichen.
Export-Csv