Ich habe die folgende Datei:
AA,true
AA,false
BB,false
CC,false
BB,true
DD,true
Ich versuche nach Duplikaten zu suchen und die Zeile zu entfernen, deren Spaltenwert gleich ist true
.
als Ausgabe sollte es sein:
AA,false
BB,false
CC,false
DD,true
text-processing
awk
sed
Hani Gotc
quelle
quelle
true
wenn es die erste Instanz der ersten Spalte ist?AA,true AA,false AA,false AA,false
Welche Ausgabe sollte in diesem Fall sein? Ich verstehe, dass diese Zeile nur entfernt werden sollte, wenn sie doppelt vorhanden ist und gleichzeitig enthälttrue
. Allefalse
Zeilen sollten auf jeden Fall unberührt bleiben. Das heißt, in diesem Fall wird nurAA, true
entfernt. Aber alle Antworten lassen nur eine Zeile -AA,false
. Einfach interessant :)Antworten:
So erweitern Sie das Skript zur Erklärung vertikal:
quelle
Einfache Version:
"false" wird alphabetisch vor "true" sortiert, und der Befehl "Awk" behält hier nur die erste Zeile für jeden einzelnen ersten Feldwert bei.
Wenn Sie "true" anstelle von "false" beibehalten möchten, sortieren Sie es in umgekehrter Reihenfolge, übergeben Sie es an denselben Awk-Befehl und sortieren Sie es anschließend erneut in umgekehrter Reihenfolge.
quelle
-u
Option verfügbar ist,sort input.txt | sort -t, -u -k1,1
sort
Anrufe verwenden? Warum nicht einfachsort -ut, -k1,1 input.txt
?-u
die erste Zeile aus der Eingabedatei unter den Duplikaten beibehalten wird ... für einen bestimmten Fall muss die Eingabe sortiert werden, bevor-u
sie angewendet werden kann ... zum Beispiel:AA,true
wird gedruckt, anstatt,AA,false
da sie in einem bestimmten Beispiel zuerst erscheint. Der gleiche Grund, warumawk -F, '!a[$1]++'
allein dieses Problem nicht lösen kannDatenstrukturen:
%h
dessen Schlüssel erste Felder sind (AAA, BBB, CCC usw.) und entsprechende Werte sind Zahlen, die die Reihenfolge angeben, in der die Schlüssel gefunden wurden. So ist zB Schlüssel AAA => 0, Schlüssel BBB => 1, Schlüssel CCC => 2.@h
dessen Elemente Zeilen sind, die in der Reihenfolge des Druckens enthalten sind. Wenn also sowohl wahr als auch falsch in Daten gefunden werden, wird der falsche Wert in das Array übernommen. OTW, wenn es einen Datentyp gibt, dann wäre dieser vorhanden.Ein anderer Weg ist die Verwendung von GNU sed:
FWIW, der POSIX-äquivalente Code für den obigen GNU-sed-Code ist unten aufgeführt:
Erläuterung
Ergebnisse
quelle
Speichern Sie für jede Eingabezeile den Wert des zweiten Felds NUR im assoziativen Array
a
(wobei das erste Feld als Schlüssel des Arrays verwendet wird), wenn wir den Wert für diesen Schlüssel noch nicht gespeichert haben . Wird sowohl für das Eingabe- als auch für das Ausgabefeldtrennzeichen verwendet. Drucken Sie das Array aus, nachdem Sie alle Eingabezeilen gelesen haben.false
,
Der wesentliche Unterschied zwischen dieser und der DopeGhoti-Version besteht darin, dass sich diese Version überhaupt nicht um den Wert von
$2
kümmert, sondern nur um den Wert von, falls vorhandena[$1]
.quelle
Zwei-Pass-
sort
LösungDer erste
sort
Durchgang gruppiert Datensätze nach Feldern,1
wobeifalse
Datensätzetrue
für jeden Datensatzblock vorangestellt sind, die einen gemeinsamen Feldwert1
haben. Der zweitesort
Durchgang ist so eingerichtet, dass ein Datensatz für jeden bestimmten Wert innerhalb des Feldes mit1
freundlicher Genehmigung von erstellt wird-u
. Da dies-u
eine stabile Sortierung impliziert, ist der eine Datensatz, der auf diese Weise erhalten wird, der erste Datensatz, der für jeden einzelnen Wert innerhalb des Felds angetroffen wird1
- wasfalse
aufgrund der im erstensort
Durchgang geleisteten Arbeit ein Datensatz im zweiten Feld istquelle