Ich habe eine CSV-Datei wie diese:
stack2@example.com,2009-11-27 01:05:47.893000000,example.net,127.0.0.1
overflow@example.com,2009-11-27 00:58:29.793000000,example.net,255.255.255.0
overflow@example.com,2009-11-27 00:58:29.646465785,example.net,256.255.255.0
...
Ich muss doppelte E-Mails (die gesamte Zeile) aus der Datei entfernen (dh eine der Zeilen [email protected]
im obigen Beispiel). Wie verwende ich uniq
nur Feld 1 (durch Kommas getrennt)? Laut man
, uniq
keine Optionen für die Spalten.
Ich habe etwas mit versucht, sort | uniq
aber es funktioniert nicht.
man sort
) erklärt. Es steht für die Start- und Stoppposition.sort
‚s Manpage sagt:‚ mit , die Prüfung für strenge Ordnung, ohne , Ausgang nur die erste einer gleichen Lauf .‘ Es ist also in der Tat "das erste Auftreten des Duplikats vor dem Sortieren".-u
--unique
-c
-c
-F
Legt das Feldtrennzeichen fest.$1
ist das erste Feld._[val]
suchtval
im Hash_
(eine reguläre Variable).++
Inkrementieren und alten Wert zurückgeben.!
gibt logisch nicht zurück.quelle
awk -F',' '{ x[$1]=$0 } END { for (i in x) print x[i] }' file
!_[$1][$2]++
kann durch die ersten beiden Felder zu sortieren verwendet werden. Meineawk
-fu ist jedoch nicht stark genug, um auf einer Reihe von Feldern einzigartig zu sein. :(Mehrere Spalten berücksichtigen.
Sortieren und geben Sie eine eindeutige Liste basierend auf Spalte 1 und Spalte 3:
-t :
Doppelpunkt ist Trennzeichen-k 1,1 -k 3,3
basierend auf Spalte 1 und Spalte 3quelle
oder wenn du uniq verwenden willst:
<mycvs.cvs tr -s ',' ' ' | awk '{print $3" "$2" "$1}' | uniq -c -f2
gibt:
quelle
cat
! Anstatt in tr zu leiten, lassen Sie tr einfach die Datei mit lesen<
. Das Durchleitencat
ist eine häufige unnötige Komplikation, die von Anfängern verwendet wird. Bei großen Datenmengen ist ein Leistungseffekt zu verzeichnen.rev
.Wenn Sie das letzte Duplikat behalten möchten, das Sie verwenden können
Welches war meine Anforderung
Hier
tac
kehrt die Datei Zeile für Zeile umquelle
Hier ist ein sehr geschickter Weg.
Formatieren Sie zuerst den Inhalt so, dass die Spalte, deren Eindeutigkeit verglichen werden soll, eine feste Breite hat. Eine Möglichkeit hierfür ist die Verwendung von awk printf mit einem Feld- / Spaltenbreitenspezifizierer ("% 15s").
Jetzt können die Optionen -f und -w von uniq verwendet werden, um vorhergehende Felder / Spalten zu überspringen und die Vergleichsbreite (Spaltenbreite) anzugeben.
Hier sind drei Beispiele.
Im ersten Beispiel ...
1) Stellen Sie die interessierende Spalte vorübergehend auf eine feste Breite ein, die größer oder gleich der maximalen Breite des Feldes ist.
2) Verwenden Sie die Option -f uniq, um die vorherigen Spalten zu überspringen, und verwenden Sie die Option -w uniq, um die Breite auf tmp_fixed_width zu beschränken.
3) Entfernen Sie nachgestellte Leerzeichen aus der Spalte, um die Breite wiederherzustellen (vorausgesetzt, es gab zuvor keine nachgestellten Leerzeichen).
Im zweiten Beispiel ...
Erstellen einer neuen Uniq-Spalte 1. Entfernen Sie diese, nachdem der Uniq-Filter angewendet wurde.
Das dritte Beispiel ist das gleiche wie das zweite, jedoch für mehrere Spalten.
quelle
Nun, einfacher als das Isolieren der Spalte mit awk. Wenn Sie alles mit einem bestimmten Wert für eine bestimmte Datei entfernen müssen, warum nicht einfach grep -v:
zB um alles mit dem Wert "col2" in der zweiten Zeile zu löschen: col1, col2, col3, col4
Wenn dies nicht gut genug ist, weil einige Zeilen möglicherweise nicht ordnungsgemäß entfernt werden, weil möglicherweise der übereinstimmende Wert in einer anderen Spalte angezeigt wird, können Sie Folgendes tun:
awk, um die beleidigende Spalte zu isolieren: z
Das -F setzt das durch "," getrennte Feld, $ 2 bedeutet Spalte 2, gefolgt von einem benutzerdefinierten Trennzeichen und dann der gesamten Zeile. Sie können dann filtern, indem Sie Zeilen entfernen, die mit dem fehlerhaften Wert beginnen:
und dann das Zeug vor dem Trennzeichen ausziehen:
(Beachten Sie, dass der Befehl sed schlampig ist, da er keine Escape-Werte enthält. Außerdem sollte das sed-Muster wirklich so etwas wie "[^ |] +" sein (dh alles, was nicht das Trennzeichen ist). Aber hoffentlich ist dies klar genug.
quelle
Wenn Sie die Datei
sort
zuerst mit sortieren , können Sie sie dann anwendenuniq
.Es scheint die Datei ganz gut zu sortieren:
Sie können auch AWK-Magie anwenden:
quelle
sort
, dannuniq
,sort
muss getan werden , bevor Sieuniq
es sonst nicht funktioniert (aber Sie können den zweiten Befehl und nur Gebrauch überspringensort -u
). Vonuniq(1)
: "Filtern Sie benachbarte übereinstimmende Zeilen von INPUT (oder Standardeingabe) und schreiben Sie in OUTPUT (oder Standardausgabe)."