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-ID: 483445

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

Ausgedruckt am: 22.11.2024 um 06:11 Uhr

Momo1412
Momo1412 09.08.2019 um 09:32:55 Uhr
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?
syscloud2019
syscloud2019 09.08.2019 um 10:57:31 Uhr
Goto Top
Es müsste hier über ein Batch Script lösbar sein, wenn es geht.
140447
140447 09.08.2019 aktualisiert um 12:37:32 Uhr
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  
Lochkartenstanzer
Lochkartenstanzer 09.08.2019 aktualisiert um 11:40:35 Uhr
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!
140447
140447 09.08.2019 aktualisiert um 11:49:35 Uhr
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
syscloud2019
syscloud2019 09.08.2019 um 12:22:18 Uhr
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;;
Lochkartenstanzer
Lochkartenstanzer 09.08.2019 um 12:22:38 Uhr
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
Lochkartenstanzer
Lochkartenstanzer 09.08.2019 aktualisiert um 12:33:50 Uhr
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?
140447
140447 09.08.2019 aktualisiert um 12:38:59 Uhr
Goto Top
Bekommt man das auch wie folgt hin:
Kein Problem s. Anpassung im Code des ursprünglichen Post oben.
syscloud2019
syscloud2019 09.08.2019 um 13:10:45 Uhr
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;
Lochkartenstanzer
Lochkartenstanzer 09.08.2019 um 13:28:40 Uhr
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
140447
140447 09.08.2019 aktualisiert um 14:01:22 Uhr
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)
Lochkartenstanzer
Lochkartenstanzer 09.08.2019 um 14:10:47 Uhr
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.
140447
140447 09.08.2019 aktualisiert um 14:20:04 Uhr
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.
syscloud2019
syscloud2019 09.08.2019 um 14:23:54 Uhr
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  
140447
140447 09.08.2019 aktualisiert um 14:45:49 Uhr
Goto Top
Nöp, siehst du aber auch selbst wenn du's ausprobiert hättest.
Zeile 7 ist dein Freund.
syscloud2019
syscloud2019 09.08.2019 um 17:05:37 Uhr
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
140777
140777 14.08.2019 aktualisiert um 16:15:51 Uhr
Goto Top
Lochkartenstanzer
Lochkartenstanzer 14.08.2019 um 16:17:52 Uhr
Goto Top
Zitat von @140777:

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

Das ist derselbe TO.

lks
140777
140777 14.08.2019 aktualisiert um 16:20:22 Uhr
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.
77559
Lösung 77559 15.08.2019 um 20:07:48 Uhr
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.