2009-04-14 26 views
13

Ich habe ein Tool, das Tests generiert und die Ausgabe vorhersagt. Die Idee ist, dass ich, wenn ich einen Fehler habe, die Vorhersage mit der tatsächlichen Ausgabe vergleichen und sehen kann, wo sie sich voneinander unterscheiden. Das Problem ist die tatsächliche Ausgabe enthält einige Zeilen zweimal, die diff verwirrt. Ich möchte die Duplikate entfernen, damit ich sie leicht vergleichen kann. Grundsätzlich so etwas wie sort -u aber ohne die Sortierung.Unix-Tool, um doppelte Zeilen aus einer Datei zu entfernen

Gibt es ein Unix-Kommandozeilen-Tool, das das kann?

+0

Mögliches Duplikat [Wie ich doppelte Zeilen in einer Datei in Unix löschen?] (Http://stackoverflow.com/questions/1444406/how-can-i-delete-duplicate-lines-in- a-file-in-unix) –

Antwort

18

uniq(1)

SYNOPSE

uniq [OPTION] ... [INPUT [OUTPUT]]

BESCHREIBUNG

Discard alle bis auf einen der aufeinanderfolgenden identischen Zeilen von INPUT (oder Standardeingang), Schreiben auf OUTPUT (oder Standardausgang).

Oder, wenn Sie auch nicht benachbarte doppelte Zeilen entfernen möchten, dieses Fragment von Perl wird es tun:

while(<>) { 
    print $_ if (!$seen{$_}); 
    $seen{$_}=1; 
} 
+0

Die Perl-Antwort funktioniert nur, wenn Sie das erste Element möchten. Das letzte wäre eine andere Lösung. – Xetius

+1

Und für diejenigen, die nicht wissen, wie man Perl verwendet, ist dies alles, was Sie brauchen, um zu tippen: perl -pe 'print, wenn $ gesehen {$ _} ++' [INPUT]> OUTPUT – reinierpost

+0

@ Xetuis, sie ' in der gleichen Zeile :) Wenn Sie die letzte Zeile möchten, legen Sie einfach den gesehenen Eintrag auf die Zeilennummer, nicht in der Schleife drucken, und drucken Sie sie in der Reihenfolge der Zeilennummer am Ende. Aber ich glaube nicht, dass das in diesem Fall notwendig ist. –

1

Wenn Sie interessiert sind benachbarte doppelte Zeilen in Entfernen verwenden uniq .

Wenn Sie alle doppelte Zeilen entfernen möchten, nicht nur benachbarte, dann ist es schwieriger.

1

Hier ist, was ich kam, während ich auf eine Antwort hier wartete (obwohl die erste (und akzeptierte) Antwort in etwa 2 Minuten kam). Ich habe diese Substitution in VIM:

%s/^\(.*\)\n\1$/\1/ 

Das heißt: für Linien sehen, wo nach dem Newline wir das gleiche wie vorher haben, und ersetzen Sie sie nur mit dem, was wir in der ersten Zeile erfasst.

uniq ist definitiv einfacher, obwohl.

24

Komplementär zu den uniq Antworten, die gut funktionieren, wenn Sie nichts dagegen haben sort Ihre Datei zuerst. Wenn Sie nicht benachbarte Zeilen entfernen müssen (oder wenn Sie Duplikate entfernen wollen, ohne die Dateien neu anordnen), die folgenden Perl Einzeiler sollte es tun (bestohlen here):

cat textfile | perl -ne '$H{$_}++ or print' 
+0

Ich denke, das ist eine saubere Antwort. Seit 6 Jahren programmieren Sie jetzt in Perl und hätten nicht an so etwas Konkretes gedacht. – Xetius

+1

Der Perl Teil ist wirklich raffiniert. Dies qualifiziert jedoch für die "Useless Use of cat" -Auszeichnung :-) (siehe http://partmaps.org/era/unix/award.html). Verwenden Sie einfach " sleske

+2

Ich habe noch nie von dieser Auszeichnung gehört! Ja, ich benutze Katze eher unentgeltlich manchmal; Ich habe keine Ahnung, wieso "cat x |" für mich besser aussieht als " y "macht meine Augen bluten: P –

1

Hier ist eine awk Implementierung , falls die Umgebung keine Perle hat (noch keine gesehen)! PS: Wenn mehrere Zeilen doppelt vorhanden sind, werden doppelte Ausgaben gedruckt.

awk '{ 

# Cut out the key on which duplicates are to be determined. 
key = substr($0,2,14) 

#If the key is not seen before, store in array,else print 
if (! s[key]) 
    s[key] = 1; 
else 
    print key; 
}' 
+4

Wenn Sie nur die ganze Zeile betrachten, die der Schlüssel ist, ist dies analog zu den Perl-Lösungen: 'awk!! C [$ 0] ++ 'Datei' –

Verwandte Themen