Ich habe eine Variable, die die folgenden durch Leerzeichen getrennten Einträge enthält.
%Vor%Wie entferne ich die Duplikate ohne zu sortieren?
%Vor%Ich habe irgendwo ein Skript gefunden, das das Entfernen der Duplikate einer Variablen bewirkt, aber den Inhalt sortiert.
%Vor%So funktioniert es:
RS (Input Record Separator) ist auf ein weißes Leerzeichen gesetzt, so dass es jedes Obst in $ Variable als einen Datensatz anstelle eines Feldes behandelt. Die nicht sortierende einzigartige Magie passiert mit! A [$ 0] ++. Da awk assoziative Arrays unterstützt, verwendet es den aktuellen Datensatz ($ 0) als Schlüssel für das Array a []. Wenn dieser Schlüssel vorher nicht gesehen wurde, wird a [$ 0] zu '0' (awks Standardwert für nicht gesetzte Indizes) ausgewertet, der dann negiert wird, um TRUE zurückzugeben. Ich nutze dann die Tatsache aus, dass awk standardmäßig $ 0 druckt, wenn ein Ausdruck TRUE zurückgibt und keine '{commands}' gegeben werden. Schließlich wird dann ein [$ 0] inkrementiert, so dass dieser Schlüssel nicht länger TRUE zurückgeben kann und somit Wiederholungswerte niemals gedruckt werden. ORS (Output Record Separator) wird ebenfalls auf ein Leerzeichen gesetzt, um das Eingabeformat zu imitieren.
Eine weniger knappe Version dieses Befehls, die die gleiche Ausgabe erzeugt, wäre die folgende:
%Vor%Ich liebe awk =)
BEARBEITEN
Wenn Sie dies in reinem Bash 2.1+ tun müssten, würde ich Folgendes vorschlagen:
%Vor%Diese Pipeline-Version arbeitet unter Beibehaltung der ursprünglichen Reihenfolge:
%Vor%Shell
%Vor%Ergebnis beim Ausführen:
%Vor%ODER wenn du gawk benutzen willst
%Vor%Perl-Lösung:
perl -le 'for (@ARGV){ $h{$_}++ }; for (keys %h){ print $_ }' $variable
@ARGV
ist die Liste der Eingabeparameter von $variable
Durchlaufen Sie die Liste und füllen Sie den h
- Hash mit der Schleifenvariablen $_
Durchlaufen Sie die Schlüssel des h
-Hashs und drucken Sie jeden einzelnen
Diese Variante druckt die Ausgabe zuerst sortiert nach Häufigkeit $h{$a} <=> $h{$b}
und dann alphabetisch $a cmp $b
perl -le 'for (@ARGV){ $h{$_}++ }; for (sort { $h{$a} <=> $h{$b} || $a cmp $b } keys %h){ print "$h{$_}\t$_" }' $variable
Diese Variation erzeugt die gleiche Ausgabe wie die letzte.
Anstelle einer Eingabe-Shell-Variable wird jedoch eine Eingabedatei 'fruits' mit einer Frucht pro Zeile verwendet:
perl -lne '$h{$_}++; END{ for (sort { $h{$a} <=> $h{$b} || $a cmp $b } keys %h){ print "$h{$_}\t$_" } }' fruits