• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

doppelte Zeilen in einer Datei löschen

Ich suche ein Befehl der
doppelte Zeilen in einer Datei löschen

Ausgang Inhalt

bla
blabla
bla
blabla
bla1

Ziel Inhalt

bla
blabla
bla1


Gruß
compi
 
Hallo,

P6CNAT schrieb:
cat datei.txt | sort -u > neuedatei.txt
Diese Methode produziert allerdings eine geordnete Liste, was vielleicht unerwünscht ist. Es gibt natürlich viele Möglichkeiten doppelte einträge zu entfernen ohne die original Reihenfolge zu verlieren. Zum Beispiel:

Ein bash script schreiben welches:

-1- die Zeilen nummeriert:

Code:
    001 bla
    002 blabla
    003 bla
    004 blabla
    005 bla1
-2- die Datei sortieren aber das erste Feld (die Nummerierung) überspringen
("sort" mit der '-k' Option) und mehrfach Zeilen löschen ('-u'):

Code:
    001 bla
    005 bla1
    004 blabla
-3- die Datei wieder sortieren:

Code:
    001 bla
    004 blabla
    005 bla1
-4- Nummerierung entfernen:

Code:
    bla
    blabla
    bla1
Gruss,
Roland
 
cutlines.pl:
Code:
#!/usr/bin/perl -w
unless (@ARGV) {
    print "Usage cutlines.pl <file>.\n";
    exit(1);
}
open(FH, "<$ARGV[0]");
my @a = <FH>; # Gulp!
close(FH);
my @b = (); my $i; my $u; my $x;
foreach $i (@a) {
    $x = 0;
    foreach $u (@b) {
        if ($i eq $u) {
            $x = 1;
            last;
        }
    }
    unless ($x) {
        push(@b, $i);
    }
}
foreach (@b) {print;}
HTH ;)
 
A

Anonymous

Gast
abgdf schrieb:
cutlines.pl:
......
HTH ;)
dafür fast tausend Zeilen :irre: mit awk geht sowas natürlich auch recht praktisch ;)
Code:
awk '{if (a[$0]==0) {a[$0]=1; print}}' testdatei.txt

robi
 
robi schrieb:
abgdf schrieb:
cutlines.pl:
......
HTH ;)
dafür fast tausend Zeilen :irre: mit awk geht sowas natürlich auch recht praktisch ;)
Code:
awk '{if (a[$0]==0) {a[$0]=1; print}}' testdatei.txt

robi
Menno, das ist natürlich kein Problem von Perl, sondern von mir.
Ein Hash ist eine sehr gute Idee. Dann also:
Code:
perl -ne 'unless($h{$_}){$h{$_}=1; print}' -i testdatei.txt
Achtung: Datei wird dabei "in place" geändert.

Man kann in Perl also beides haben. Ich bin dabei aber mehr ein "Skript-" und weniger ein "Einzeiler-Typ".

Gruß
 
A

Anonymous

Gast
abgdf schrieb:
Ein Hash ist eine sehr gute Idee. Dann also:
Code:
perl -ne 'unless($h{$_}){$h{$_}=1; print}' -i testdatei.txt

Na es geht doch. :D Aber da sieht man wieder mal, wenn man in einer Programmiersprache zu viel Möglichkeiten hat, dann kommt man oftmals in Versuchung ein Problem viel zu kompliziert zu lösen.

robi
 
Die kryptischen Einzeiler funktionieren ja tatsächlich :irre:
Verstanden habe ich die aber nicht, muss wohl noch eine Nacht drüber schlafen.

Gruß
Georg
 
A

Anonymous

Gast
P6CNAT schrieb:
Verstanden habe ich die aber nicht
Mal als Denkanstoß. Du hast die folgenden Namen auf einem Zettel
Code:
Oma
Opa
Tante
Opa
Egon
Die willst du alle zu deinem Geburtstag einladen. Also rufst du sie der Reihe nach an. Wenn das 2. Mal der Opa erscheint, fällt dir ein, "Moment, den hab ich ja schon angerufen" und überspringst diese Zeile auf deiner Liste einfach.

Genau so funktionieren die für dich unverständlichen Einzeiler. Und zwar wird das wie folgt erledigt. Aber wir fangen ein Stück weiter vorne im Urschleim an.

ARRAY ist dir doch bestimmt ein Begriff. Also meist sehen die wie folgt aus, mal nur so schematisch . Da hat man einfach fortlaufende Zahlen als Index.
Code:
STRING V[5]={"Oma","Opa","Tante","Opa","Egon"};
for (i=0;i<5;i++){
    printf ("%s \n",V[i]);
}
Und jetzt stell dir mal folgende Arrayvariante gedanklich vor.
Code:
V["Oma"]="12.8.1943" 
V["Opa"]="8.10.1939"
V["Tante"]="24.2.1962"
V["Egon"]="31.8.1978"
Also ein Array V[] das als Index einen frei definierbaren String enthält, und wo man nicht vorher festlegen muss wie viele Elemente die Array Variable aufnehmen kann und wo ein unitialisiertes Element bei der Abfrage immer NULL ist. Und in den einzelnen Elementen kann man dann etwas speichern, hier haben wir im Beispiel mal einen Datumsstring dort abgelegt. Für unsere Aufgabe währe es aber schon ausreichend wenn wir dort eine 1 reinschreiben würden sobald wir erfolgreich angerufen haben, wenn noch nicht, und wenn wir einen neuen Indexeintrag benützen würden, dann würde immer eine 0 dort stehen.

Jetzt könnte man doch aber auch einfach schematisch gesehen folgendes machen.
Code:
if (V["Oma"]==0) then {V["Oma"]=1; print "Oma"}
wenn also ein Element des Array mit dem Index "Oma" den Wert NULL hat, dann setze dort den Wert 1 und schreibe den Index, also "Oma"
Kommt jetzt "Oma" nochmal zu einem späteren Zeitpunkt, dann hat das Element des Array mit dem Index "Oma" nicht mehr den Wert 0 und "Oma" wird nicht mehr geschrieben.

Und genau so arbeiten diese kleinen Einzeiler, Als Index für die Array Elemente wird einfach die komplette Zeile verwendet. ;) ;) ;)
Und solche Bölsartigkeiten funktionieren in einer ganzen Reihe von modernen Programmiersprachen. Zum Einlesen eventuell mal hier anfangen. Wo sich sowas anbietet kann man damit oft sehr effektiv programmieren.


robi
 

framp

Moderator
Teammitglied
Assoziative Arrays sind doch schon was Feines. Deshalb ist Robi - wie auch ich - ein Fan davon
 
Hi robi,

herzhaften Dank für die sehr eingängige Erläuterung aus dem Urschleim :), jetzt ist der Groschen gefallen :thumbs:.

framp schrieb:
Assoziative Arrays sind doch schon was Feines.
Zumindest vom Programmieraufwand sehr effizient. Gewöhnungsbedürftig ist es aber schon. Z.B. gaaanz lange Zeilen aus einer CSV Datei als Index in einem assoziativen Array zu verwenden. Irgendwie gruselig, wenn man gewohnt ist Indizes möglichst kurz und effizient zu wählen ;) .

Gruß
Georg
 

framp

Moderator
Teammitglied
P6CNAT schrieb:
... Gewöhnungsbedürftig ist es aber schon. Z.B. gaaanz lange Zeilen aus einer CSV Datei als Index in einem assoziativen Array zu verwenden. Irgendwie gruselig, wenn man gewohnt ist Indizes möglichst kurz und effizient zu wählen ;) ...
Das ist immer eine Frage des Einsatzes: Eine DB würde ich damit auch nicht realisieren. Aber für kleinere Dinge (one liners etc) oder Prototypen bestens geeignet.
 
robi[/quote]
Menno, das ist natürlich kein Problem von Perl, sondern von mir.
Ein Hash ist eine sehr gute Idee. Dann also:
Code:
perl -ne 'unless($h{$_}){$h{$_}=1; print}' -i testdatei.txt
Achtung: Datei wird dabei "in place" geändert.

Man kann in Perl also beides haben. Ich bin dabei aber mehr ein "Skript-" und weniger ein "Einzeiler-Typ".

Gruß
Danke hat geholfen
 
Oben