syscloud2019
Goto Top

Batch: Doppelte Datensätze in einer CSV kennzeichnen

Guten Morgen in die Runde,

ich habe eine .csv mit relativ vielen Spalten, bei der es sein kann, dass doppelte Werte anhand der ersten Spalte vorhanden sind.
Habe ich mit Batch eine Möglichkeit doppelte Datensätze in der letzten Spalte mit einer "1" zu kennzeichnen?

Ausgangsdatei:

500;100;500;100;400;
350;100;500;100;400;
500;100;500;100;400;
400;100;500;100;400;

Gewünschte Datei:

500;100;500;100;400;1;
350;100;500;100;400;;
500;100;500;100;400;1;
400;100;500;100;400;;

Ich wünsche einen schönen Tag,

Bernd.

Content-Key: 483445

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

Printed on: April 25, 2024 at 11:04 o'clock

Member: Momo1412
Momo1412 Aug 09, 2019 at 07:32:55 (UTC)
Goto Top
Also unabhängig davon, ob das mit einem Batch-Script lösbar wäre

könntest du das doch sicherlich mit Excel oder einer Datenbank lösen, oder etwa nicht?
Member: syscloud2019
syscloud2019 Aug 09, 2019 at 08:57:31 (UTC)
Goto Top
Es müsste hier über ein Batch Script lösbar sein, wenn es geht.
Mitglied: 140447
140447 Aug 09, 2019 updated at 10:37:32 (UTC)
Goto Top
Machs gleich mit Powershell, wenn die Spalten keine Überschriften haben (gehe ich von aus da du hier keine aufgelistet hast) dann:
$quelle = 'D:\test.csv'  
$ziel = 'D:\test_out.csv'  
$numcols = (gc $quelle -head 1).split(";").count  
$csv = Import-CSV $quelle -Delimiter ";" -Header (1..$numcols)  
($csv | group '1' | %{  
    if ($_.Count -gt 1){
        $_.Group | %{$_.$numcols = 1}
        $_.Group
    }else{
        $_.Group
    }
} | ConvertTo-CSV -delimiter ";" -NoType | select -Skip 1) -replace '"','' | sc $ziel  
Member: Lochkartenstanzer
Lochkartenstanzer Aug 09, 2019 updated at 09:40:35 (UTC)
Goto Top
Moin,

Mit (g)awk ist das ein Einzeiler:
gawk <EINGABE.CSV >AUSGABE.CSV  -F ";" ' { if ( match ($2$3$4$5, $1) ) { print $1";"$2";"$3";"$4";"$5";1;" } else { print  $1";"$2";"$3";"$4";"$5";;" } } '

lks

PS: (g)awk ist auch im linux-subsystem für Windows enthalten.

PPS: Bei Deiner Ausgabe ist ein Fehler in der 4. Zeile:
400;100;500;100;400;;

Da müßte eine 1 stehen!
Mitglied: 140447
140447 Aug 09, 2019 updated at 09:49:35 (UTC)
Goto Top
mit relativ vielen Spalten
face-wink

Da müßte eine 1 stehen!
Er will doch laut seiner Aussage nur die erste Spalte aller Datensätze vergleichen?! Denn dann ist das oben von ihm korrekt
Member: syscloud2019
syscloud2019 Aug 09, 2019 at 10:22:18 (UTC)
Goto Top
Zitat von @140447:

Machs gleich mit Powershell, wenn die Spalten keine Überschriften haben (gehe ich von aus da du hier keine aufgelistet hast) dann:
> $quelle = 'D:\test.csv'  
> $ziel = 'D:\test_out.csv'  
> $numcols = (gc $quelle -head 1).split(";").count  
> $csv = Import-CSV $quelle -Delimiter ";" -Header (1..$numcols)  
> $csv | group '1' | %{  
>     if ($_.Count -gt 1){
>         $_.Group | %{$_.$numcols = 1}
>         $_.Group
>     }else{
>         $_.Group
>     }
> } | export-csv $ziel -NoType -Delimiter ";" -Encoding UTF8  
> 

Ich habe hier jetzt folgende Ausgabe in der CSV:

"1";"2";"3";"4";"5";"6"  
"500";"100";"500";"100";"400";"1"  
"500";"100";"500";"100";"400";"1"  
"350";"100";"500";"100";"400";""  
"400";"100";"500";"100";"400";  

Bekommt man das auch wie folgt hin:

500;100;500;100;400;1;
500;100;500;100;400;1;
350;100;500;100;400;;
400;100;500;100;400;;
Member: Lochkartenstanzer
Lochkartenstanzer Aug 09, 2019 at 10:22:38 (UTC)
Goto Top
Zitat von @140447:

mit relativ vielen Spalten
face-wink

Da müßte eine 1 stehen!
Er will doch laut seiner Aussage nur die erste Spalte aller Datensätze vergleichen?! Denn dann ist das oben von ihm korrekt

Nein,

in Zeile 4 ist die erste Spalte die gleiche wie die fünfte.

Ansonsten hat er ungenau spezifiziert.


lks
Member: Lochkartenstanzer
Lochkartenstanzer Aug 09, 2019 updated at 10:33:50 (UTC)
Goto Top
Zitat von @syscloud2019:

Bekommt man das auch wie folgt hin:

> 500;100;500;100;400;1;
> 500;100;500;100;400;1;
> 350;100;500;100;400;;
> 400;100;500;100;400;;
> 


Moin,

Mein "Programm" Liefert:
500;100;500;100;400;1;
350;100;500;100;400;;
500;100;500;100;400;1;
400;100;500;100;400;1;

Jetzt mußt Du nur noch sagen, was Du in der letzten Zeile stehen haben wilstl und ggf. Deine Spezifikation nachbessern face-smile

lks

PS: Die Reihenfolge der Zeilen hat sich bei Dir geändert. Ist das gewünscht?
Mitglied: 140447
140447 Aug 09, 2019 updated at 10:38:59 (UTC)
Goto Top
Bekommt man das auch wie folgt hin:
Kein Problem s. Anpassung im Code des ursprünglichen Post oben.
Member: syscloud2019
syscloud2019 Aug 09, 2019 at 11:10:45 (UTC)
Goto Top
Das dass letzte Zeichen auch immer noch ein Semikolon ist, geht nicht oder?

500;100;500;100;400;1;
350;100;500;100;400;;
500;100;500;100;400;1;
400;100;500;100;400;1;
Member: Lochkartenstanzer
Lochkartenstanzer Aug 09, 2019 at 11:28:40 (UTC)
Goto Top
Zitat von @syscloud2019:

Das dass letzte Zeichen auch immer noch ein Semikolon ist, geht nicht oder?


Natürlich geht das. Paß einfach das Skript an.

lks
Mitglied: 140447
140447 Aug 09, 2019 updated at 12:01:22 (UTC)
Goto Top
Zitat von @syscloud2019:

Das dass letzte Zeichen auch immer noch ein Semikolon ist, geht nicht oder?
Ein abschließendes Semikolon bedeutet das noch eine neue letzte Spalte kommt, also ist dein dann deine Nummer in der vorletzten Spalte! Eine echte CSV hat keine abschließenden Semikolons hinter der letzten Spalte.
Also schreib die Daten in die vorletzte Spalte ($numcols -1)
Member: Lochkartenstanzer
Lochkartenstanzer Aug 09, 2019 at 12:10:47 (UTC)
Goto Top
Zitat von @140447:

Ein abschließendes Semikolon bedeutet das noch eine neue letzte Spalte kommt, also ist dein dann deine Nummer in der vorletzten Spalte! Eine echte CSV hat keine abschließenden Semikolons hinter der letzten Spalte.

Nein, Ein Semikolon am Schluß bedeutet, daß da noch ein leeres Feld hintendran ist.

Von daher haben manche "echten" CSVs öfter man Semikolons am Schluß. face-smile

lks

PS: Das ist immer von der "Programmlogik" des entsprechenden Programmierers und der Spezifikation des Auftraggebers abhängig.
Mitglied: 140447
140447 Aug 09, 2019 updated at 12:20:04 (UTC)
Goto Top
noch ein leeres Feld hintendran ist.
Leeres Feld oder leere Spalte, ist im Endeffekt das selbe, reine Auslegungssache face-smile.

Kann er sich jetzt selbst dran pappen wie er lustig ist.
Member: syscloud2019
syscloud2019 Aug 09, 2019 at 12:23:54 (UTC)
Goto Top
Zitat von @140447:

noch ein leeres Feld hintendran ist.
Leeres Feld oder leere Spalte, ist im Endeffekt das selbe, reine Auslegungssache face-smile.

Kann er sich jetzt selbst dran pappen wie er lustig ist.

Meinst Du so?

$quelle = 'D:\test.csv'  
$ziel = 'D:\test_out.csv'  
$numcols = (gc $quelle -head 1).split(";").count  
$csv = Import-CSV $quelle -Delimiter ";" -Header (1..$numcols-1)  
($csv | group '1' | %{  
    if ($_.Count -gt 1){
        $_.Group | %{$_.$numcols = 1}
        $_.Group
    }else{
        $_.Group
    }
} | ConvertTo-CSV -delimiter ";" -NoType | select -Skip 1) -replace '"','' | sc $ziel  
Mitglied: 140447
140447 Aug 09, 2019 updated at 12:45:49 (UTC)
Goto Top
Nöp, siehst du aber auch selbst wenn du's ausprobiert hättest.
Zeile 7 ist dein Freund.
Member: syscloud2019
syscloud2019 Aug 09, 2019 at 15:05:37 (UTC)
Goto Top
Zitat von @140447:

Nöp, siehst du aber auch selbst wenn du's ausprobiert hättest.
Zeile 7 ist dein Freund.

$quelle = 'D:\test.csv'  
$ziel = 'D:\test_out.csv'  
$numcols = (gc $quelle -head 1).split(";").count  
$csv = Import-CSV $quelle -Delimiter ";" -Header (1..$numcols)  
($csv | group '1' | %{  
    if ($_.Count -gt 1){
        $_.Group | %{$_.$numcols = -1}
        $_.Group
    }else{
        $_.Group
    }
} | ConvertTo-CSV -delimiter ";" -NoType | select -Skip 1) -replace '"','' | sc $ziel  

Hier bekomme ich leider nicht die korrekte Ausgabe face-sad
Mitglied: 140777
140777 Aug 14, 2019 updated at 14:15:51 (UTC)
Goto Top
Member: Lochkartenstanzer
Lochkartenstanzer Aug 14, 2019 at 14:17:52 (UTC)
Goto Top
Zitat von @140777:

Hier rein schauen:
Frage zu Powershell - fast perfektes Skript vorhanden

Das ist derselbe TO.

lks
Mitglied: 140777
140777 Aug 14, 2019 updated at 14:20:22 (UTC)
Goto Top
Zitat von @Lochkartenstanzer:
Das ist derselbe TO.
Ein doppeltes Lottchen mit zwei Accounts? Naja egal, der Nachwelt sollte es trotzdem vielleicht noch nutzen.
Mitglied: 77559
Solution 77559 Aug 15, 2019 at 18:07:48 (UTC)
Goto Top
Eine weitere PowerShell Lösung.

Anzahl Spalten ist hier egal

Die Eingabe wird eingelesen,
die erste Spalte wird in eine Hash-Tabelle eingetragen und inkrementiert.
Beim abarbeiten der Eingabe wird der Zähler minus 1 an die Zeile angehängt
(sollten mehr als 2 Dubletten vorkommen steht dann keine 1, sondern 2..)

$Eingabe = Get-Content '.\Eingabe.csv'  
$Ausgabe = '.\Ausgabe.csv'  
$Hash = @{}
$Eingabe | ForEach-Object{$Hash[($_.Split(';')[0])]+=1}  
$Eingabe | ForEach-Object{'{0}{1:#};' -f $_,($Hash[($_.Split(';')[0])] -1)} | Set-Content $Ausgabe  

500;100;500;100;400;1;
350;100;500;100;400;;
500;100;500;100;400;1;
400;100;500;100;400;;

Zwischenergebnis:
> $Hash                                                                                                                             
Name                           Value
----                           -----
500                            2
350                            1
400                            1

Gruß
LotPings

PS: Du solltest, wenn eine Antwort deine Lösung ist, entsprechend markieren.