Die Datei file1.txt enthält Zeilen wie:
/api/purchase/<hash>/index.html
Beispielsweise:
/api/purchase/12ab09f46/index.html
Die Datei file2.csv enthält Zeilen wie:
<hash>,timestamp,ip_address
Beispielsweise:
12ab09f46,20150812235200,22.231.113.64
a77b3ff22,20150812235959,194.66.82.11
Ich möchte file2.csv filtern und alle Zeilen entfernen, in denen der Wert von Hash auch in file1.txt vorhanden ist. Das heißt:
cat file1.txt | extract <hash> | sed '/<hash>/d' file2.csv
oder sowas.
Es sollte einfach sein, aber ich scheine nicht in der Lage zu sein, es zum Laufen zu bringen.
Kann jemand bitte eine funktionierende Pipeline für diese Aufgabe bereitstellen?
quelle
cat
, nurcut -d / -f 4 file1.txt
. Oder wenn Sie den sequentiellen Look bevorzugen,<file1.txt cut -d / -f 4
Mögliche
awk
Lösung:Zuerst lesen wir
file1.txt
mitFS
(Feldtrennzeichen) "/" und erstellen das Array x mit Schlüsselwerten aus dem Feld,$4
das der gewünschte Hash ist. Als nächstes werden wir zweite Datei lesenfile2.txt
EinstellungFS
sein,
und zu prüfen , ob Wert des Feldes$1
nicht als Schlüssel in einem Array existiertx
und wenn es uns es nicht gedruckt wird .Das gleiche idiomatischere wie in den Kommentaren vorgeschlagen könnte sein:
quelle
!($1 in x)
statt{ if (!($1 in x)) print $0; }
awk
basierte Lösung zu lernen ... auf lange Sicht werden Sie lernen, sich für Lösungen zu interessieren, die der Einfachheit halber mit weniger Rohren erreicht werden können ... :)Für GNU sed
wo erste sed produzieren Liste von Hashes in sed-Befehl-Format wie
/12ab09f46\|a77b3ff22\|..../d
es übertragen nächsten sed -script die daher von der Eingabe über Befehl liest-f -
Option.Gleiches gilt für grep
oder ohne Perl-Ausdrücke:
oder noch besser mit Schnitt :
quelle
Beachten Sie, dass die Suchstiche
/$key/
und^$key,
um die Ergebnisse zu reduzieren, entweder zwischen zwei Schrägstrichen (Datei 1) oder als erster Eintrag einer Zeile und gefolgt von einem Komma (Datei 2) liegen. Dies sollte es sicher machen, wenn Schlüssel aussehenin Datei 2 oder ähnlich
in Datei 1
quelle
Ich habe gerade den folgenden Liner ausprobiert und er scheint den Job zu machen:
Bitte ersetzen Sie zuerst -ri durch -re , um es zu testen. -re macht einen Trockenlauf, und wenn alles in Ordnung ist, kannst du ihn mit -ri laufen lassen
quelle
Zusätzlich zur Antwort von Gabriele Lana beachten Sie bitte, dass für den BSD-Einfügebefehl ein Bindestrich angegeben werden muss, um Inhalte von der Standardeingabe lesen zu können.
Handbuch des Einfügebefehls
Das letzte muss also wie unten geändert werden
quelle