Überprüfen Sie, ob alle Zeilen einer Datei eindeutig sind

11

Ich habe eine Textdatei mit Zeilen wie diesen:

This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
.
.
.
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520

Wie kann ich mir der Einzigartigkeit jeder Zeile sicher sein?

HINWEIS: Ziel ist es, die Datei zu testen und nicht zu ändern, wenn doppelte Zeilen vorhanden sind.

snr
quelle
1
Verlinken in: unix.stackexchange.com/q/76049/117549
Jeff Schaller
1
Möchten Sie überprüfen, ob alle Zeilen eindeutig sind, oder möchten Sie Duplikate entfernen?
8bittree
1
@ 8bittree - möchte nur sicher sein, Einzigartigkeit
snr

Antworten:

24
[ "$(wc -l < input)" -eq "$(sort -u input | wc -l)" ] && echo all unique
Jeff Schaller
quelle
Genau das, was ich gesagt hätte, außer mit uniqstattsort -u
Nonny Moose
1
Wenn die Eingabe nicht bereits sortiert ist, uniqwäre dies ein großer Fehler. es werden nur benachbarte Zeilen dedupliziert!
Alexis
1
Wenn man sich für die Schuldigen interessiert, sort <file> | uniq -dwürde man die Duplikate drucken.
Rolf
25

Awk Lösung:

awk 'a[$0]++{print "dupes"; exit(1)}' file && echo "no dupes"
iruvar
quelle
4
+1 Die akzeptierte Antwort liest die gesamte Datei zweimal durch, während diese beendet wird, sobald sie bei einem Lesevorgang auf eine doppelte Zeile stößt. Dies funktioniert auch mit Piped-Eingaben, während die anderen Dateien benötigt werden, die erneut gelesen werden können.
JoL
Könnten Sie nicht den Schub echoin END?
Ignacio Vazquez-Abrams
2
@ IgnacioVazquez-Abrams Es gibt wirklich keinen Sinn im Echo. Tun && echooder || echoist eine Konvention in Antworten, um anzuzeigen, dass ein Befehl mit dem Exit-Statuscode das Richtige tut. Das Wichtigste ist das exit(1). Idealerweise würden Sie dies so verwenden if has_only_unique_lines file; then ..., nicht if [[ $(has_only_unique_lines file) = "no dupes" ]]; then ..., das wäre dumm.
JoL
2
Wenn andere Antworten die Datei zweimal lesen, um Speicherplatz zu sparen, wird die gesamte Datei in den Speicher eingelesen, wenn keine Dupes vorhanden sind.
Kusalananda
1
@Kusalananda Während dies die gesamte Datei in den Speicher liest, wenn keine Dupes vorhanden sind, sortwird auch will verwendet, unabhängig davon, ob es Dupes gibt oder nicht, oder? Wie spart das Speicher?
JoL
21

Verwenden von sort/ uniq:

sort input.txt | uniq

Um nur nach doppelten Zeilen -dzu suchen, verwenden Sie die Option für uniq. Dies zeigt nur doppelte Zeilen an, wenn keine vorhanden sind, wird nichts angezeigt:

sort input.txt | uniq -d
jesse_b
quelle
Das ist mein Goto. Ich bin mir nicht sicher, was die anderen Antworten mit den höheren Stimmen bieten, was diese nicht bieten.
user1717828
1
Es ist eine gute Alternative, Duplikate zu entfernen.
Snr
1
Das macht nicht was er will. Er möchte wissen, ob es Duplikate gibt, nicht entfernen.
Barmar
@Barmar: Obwohl es so scheint, ist die Frage immer noch unklar. Sowie OPs Kommentar, der versucht, es zu klären.
Jesse_b
Es gibt eine ausstehende Bearbeitung, die mehr Klarheit bietet.
Barmar
5

TLDR

Die ursprüngliche Frage war unklar und lautete, dass das OP lediglich eine eindeutige Version des Inhalts einer Datei wünschte. Das ist unten gezeigt. In der seitdem aktualisierten Form der Frage gibt das OP nun an, dass es lediglich wissen möchte, ob der Inhalt der Datei eindeutig ist oder nicht.


Testen Sie, ob der Inhalt der Datei eindeutig ist oder nicht

Sie können einfach verwenden sort, um zu überprüfen, ob eine Datei eindeutig ist oder Duplikate wie folgt enthält:

$ sort -uC input.txt && echo "unique" || echo "duplicates"

Beispiel

Angenommen, ich habe diese beiden Dateien:

Beispieldatei duplizieren
$ cat dup_input.txt
This is a thread  139737522087680
This is a thread  139737513694976
This is a thread  139737505302272
This is a thread  139737312270080
This is a thread  139737203164928
This is a thread  139737194772224
This is a thread  139737186379520
eindeutige Beispieldatei
$  cat uniq_input.txt
A
B
C
D

Wenn wir nun diese Dateien analysieren, können wir feststellen, ob sie eindeutig sind oder Duplikate enthalten:

Testduplikatdatei
$ sort -uC dup_input.txt && echo "unique" || echo "duplicates"
duplicates
eindeutige Datei testen
$ sort -uC uniq_input.txt && echo "unique" || echo "duplicates"
unique

Originalfrage (eindeutiger Inhalt der Datei)

Kann mit nur gemacht werden sort:

$ sort -u input.txt
This is a thread  139737186379520
This is a thread  139737194772224
This is a thread  139737203164928
This is a thread  139737312270080
This is a thread  139737505302272
This is a thread  139737513694976
This is a thread  139737522087680
slm
quelle
3

Normalerweise zähle ich sortdie Datei und uniqzähle dann die Anzahl der Duplikate. Dann sehe ich sortnoch einmal die Duplikate am Ende der Liste.

Ich habe den von Ihnen angegebenen Beispielen ein Duplikat hinzugefügt:

$ sort thread.file | uniq -c | sort
      1 This is a thread  139737186379520
      1 This is a thread  139737194772224
      1 This is a thread  139737203164928
      1 This is a thread  139737312270080
      1 This is a thread  139737513694976
      1 This is a thread  139737522087680
      2 This is a thread  139737505302272

Da ich die Manpage uniqschon eine Weile nicht mehr gelesen habe , habe ich schnell nach Alternativen gesucht. Im Folgenden ist die zweite Sortierung nicht mehr erforderlich, wenn Sie nur Duplikate anzeigen möchten:

$ sort thread.file | uniq -d
This is a thread  139737505302272
Carlos Hanson
quelle
Es ist in der Tat eine gute Alternative. #rez
snr
2

Wenn keine Duplikate vorhanden sind, sind alle Zeilen eindeutig:

[ "$(sort file | uniq -d)" ] && echo "some line(s) is(are) repeated"

Beschreibung: Sortieren Sie die Dateizeilen, um wiederholte Zeilen fortlaufend zu machen (sortieren).
Extrahieren Sie alle aufeinander folgenden Zeilen, die gleich sind (uniq -d).
Wenn der Befehl über ( [...]) ausgegeben wird , &&drucken Sie ( ) eine Nachricht.

Isaac
quelle
2

Dies wäre ohne eine Perl-Antwort nicht vollständig!

$ perl -ne 'print if ++$a{$_} == 2' yourfile

Dadurch wird jede nicht eindeutige Zeile einmal gedruckt. Wenn also nichts gedruckt wird, enthält die Datei alle eindeutigen Zeilen.

frapadingue
quelle
1

Verwenden cmpund sortin bash:

cmp -s <( sort file ) <( sort -u file ) && echo 'All lines are unique'

oder

if cmp -s <( sort file ) <( sort -u file )
then
    echo 'All lines are unique'
else
    echo 'At least one line is duplicated'
fi

Dies würde die Datei jedoch zweimal sortieren, genau wie die akzeptierte Antwort.

Kusalananda
quelle