Ich habe die sed
Antwort nicht lange nach dem Posten dieser Frage gefunden. sed
Bisher hat noch niemand davon Gebrauch gemacht. Hier ist es:
sed '$!N;/^\(.*\)\n\1$/d;P;D'
Ein bisschen Herumspielen mit dem allgemeineren Problem (wie wäre es mit dem Löschen von Zeilen in Dreier- oder Vier- oder Fünfersätzen?) Ergab die folgende erweiterbare Lösung:
sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
Erweitert, um Dreifache von Zeilen zu entfernen:
sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
Oder um Quads von Zeilen zu entfernen:
sed -e ':top' -e '$!{/\n.*\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1\n\1$/d;P;D' temp
sed
hat einen zusätzlichen Vorteil gegenüber den meisten anderen Optionen, nämlich die Fähigkeit, wirklich in einem Stream zu arbeiten, wobei nicht mehr Speicher benötigt wird als die tatsächliche Anzahl der auf Duplikate zu überprüfenden Zeilen.
Wie in den Kommentaren erwähnt , ist das Setzen des Gebietsschemas auf C erforderlich, um zu vermeiden, dass Zeilen, die Mehrbytezeichen enthalten, nicht ordnungsgemäß entfernt werden. So werden die obigen Befehle:
LC_ALL=C sed '$!N;/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n/!{N;b top' -e '};};/^\(.*\)\n\1$/d;P;D' temp
LC_ALL=C sed -e ':top' -e '$!{/\n.*\n/!{N;b top' -e '};};/^\(.*\)\n\1\n\1$/d;P;D' temp
# Etc.
C
ungültiges Zeichen in diesem Gebietsschema festlegen , andernfalls schlägt der Befehl fehl.Es ist nicht sehr elegant, aber so einfach, wie ich es mir vorstellen kann:
Das substr () schneidet nur die
uniq
Ausgabe ab. Das funktioniert, bis Sie mehr als 9.999.999 Duplikate einer Zeile haben (in diesem Fall kann die Ausgabe von uniq über 9 Zeichen hinausgehen).quelle
uniq -c input | awk '{if ($1 %2 == 1) { print $2 } }'
und es schien genauso gut zu funktionieren. Aus irgendeinem Grund ist diesubstr
Version besser?$2
um$NF
robuster zu sein?foo bar
.uniq
(zumindest in GNU coreutils) scheint genau 9 Zeichen vor dem Text selbst zuverlässig zu verwenden; Ich kann dies jedoch nirgendwo dokumentieren und es ist nicht in den POSIX-Spezifikationen enthalten .Probieren Sie dieses
awk
Skript aus:Es wird davon ausgegangen, dass die
lines.txt
Datei sortiert ist.Der Test:
quelle
Mit
pcregrep
für eine gegebene Probe:oder allgemeiner:
quelle
Wenn die Eingabe sortiert ist:
quelle
pineapple\napple\ncoconut
und die Ausgabe istpinecoconut
.\n
anstelle des$
angegebenen/m
Modifikators verwenden, aber dann wurde mir klar, dass bei Verwendung$
eine leere Zeile anstelle von gelöschten Zeilen verbleibt. Sieht jetzt gut aus; Ich habe die falsche Version entfernt, da sie nur Rauschen hinzufügt. :)Das gefällt mir
python
zum Beispiel mitpython
2.7+quelle
Da ich die Frage, für die ich mich entschieden habe, unter Verwendung eines Hashs für jeden Datensatz für awk verstanden habe, gehe ich in diesem Fall davon aus, dass RS = \ n ist gerade Anzahl von Wiederholungen anstelle der ungeraden mit einem Parameter oder einem kleinen Dialog. Jede Zeile wird als Hash verwendet und ihre Anzahl erhöht. Am Ende der Datei wird das Array gescannt und jede gerade Anzahl der Datensätze gedruckt. Ich beziehe die Anzahl ein, um zu überprüfen, aber das Entfernen eines [x] reicht aus, um dieses Problem zu lösen.
HTH
countlines code
Beispieldaten:
Probelauf:
quelle
awk
Code, aber leider sindawk
assoziative Arrays überhaupt nicht geordnet, noch sind sie ordnungserhaltend.sort
.!=0
impliziert wird, wieawk
Zahlen in wahre / falsche Werte konvertiert werden, wodurch diese aufawk '{a[$0]++}END{for(x in a)if(a[x]%2)print x}'
Wenn die Eingabe sortiert ist, wie sieht es damit aus
awk
:quelle
mit perl:
quelle
Shell-Konstrukte verwenden,
quelle
$b
).Fun Puzzle!
In Perl:
Ausführlich in Haskell:
Knapp in Haskell:
quelle
a version: Ich verwende "Begrenzer", um die innere Schleife zu vereinfachen (es wird davon ausgegangen, dass die erste Zeile nicht
__unlikely_beginning__
mit der Zeile: endet__unlikely_ending__
, und füge diese spezielle Begrenzerzeile am Ende der eingegebenen Zeilen hinzu Algorithmus kann beides annehmen:)So :
quelle