Gibt es ein Tool, das Zeilen abrufen kann, die in Datei A enthalten sind, in Datei B jedoch nicht? Ich könnte ein kleines einfaches Skript mit zB Perl schreiben, aber wenn so etwas schon existiert, werde ich von jetzt an meine Zeit sparen.
command-line
Gänseblümchen
quelle
quelle
Antworten:
Ja. Das Standardwerkzeug
grep
zum Durchsuchen von Dateien nach Textzeichenfolgen kann verwendet werden, um alle Zeilen in einer Datei von einer anderen zu subtrahieren.Dies funktioniert, indem jede Zeile in DateiB als Muster (
-f fileB
) und als einfache Zeichenfolge (nicht als regulärer regulärer Ausdruck) (-F
) behandelt wird. Sie erzwingen die Übereinstimmung in der gesamten Zeile (-x
) und drucken nur die Zeilen aus, die nicht übereinstimmen (-v
). Aus diesem Grund drucken Sie die Zeilen in Datei A aus, die nicht dieselben Daten wie die Zeilen in Datei B enthalten.Der Nachteil dieser Lösung ist, dass die Zeilenreihenfolge nicht berücksichtigt wird. Wenn Ihre Eingabe doppelte Zeilen an verschiedenen Stellen enthält, erhalten Sie möglicherweise nicht das, was Sie erwarten. Die Lösung hierfür ist die Verwendung eines echten Vergleichstools wie z
diff
. Sie könnten dies tun, indem Sie eine Diff-Datei mit dem Kontextwert in 100% der Zeilen in der Datei erstellen und dann nur die Zeilen analysieren, die beim Konvertieren von Datei A in Datei B entfernt würden. (Beachten Sie, dass dieser Befehl auch das Diff entfernt Formatierung, nachdem es die richtigen Linien bekommt.)quelle
-u
Argument in Kleinbuchstaben nimmt tatsächlich einen Parameter einer Zahl an, solange auf ihn kein Leerzeichen folgt. Der Vorteil, den ich vorher hatte, ist, dass es mit oder ohne Wert funktioniert, sodass Sie in dieser Unterbefehlsroutine etwas verwenden können, das keine Ausgabe zurückgibt. Großbuchstaben '-U' erfordern dagegen ein Argument.diff
Pipeline funktioniert ein Vergnügen, danke.grep
erforderlichen zu verarbeiten. Beispiel:grep -F -x -v -f <(sort fileB) <(sort fileA)
diff
ist, dass die Position in der Datei berücksichtigt wird.Die Antwort hängt stark von der Art und dem Format der zu vergleichenden Dateien ab.
Wenn die Dateien, die Sie vergleichen, sortierte Textdateien sind, kann das von Richard Stallman und Davide McKenzie aufgerufene GNU-Tool die von
comm
Ihnen gewünschte Filterung durchführen. Es ist Teil der Coreutils.Beispiel
Angenommen, Sie haben die folgenden 2 Dateien:
Zeilen in der Datei
b
, die nicht in der Datei enthalten sinda
:quelle
comm
; Leidercomm
erfordert sortierte Dateien<()
? Es funktioniert und ich verstehe, aber gibt es einen Namen für diese Verrücktheit?<()
wird auch als Prozesssubstitution bezeichnet .comm
wurde ursprünglich um 1973 von jemandem bei Bell Labs geschrieben, nicht von rms. Sie beziehen sich auf die GNU-Implementierung, die viel später erfolgte. Im Laufe der Jahre gab es viele verschiedene Implementierungen der Unix-Dienstprogramme.von stackoverflow ...
-23 unterdrückt die Zeilen, die sich in beiden Dateien oder nur in Datei 2 befinden. Die Dateien müssen sortiert werden (sie sind in Ihrem Beispiel), aber wenn nicht, leiten Sie sie zuerst durch sort ...
Siehe die Manpage hier
quelle
Die Methoden grep und comm (with sort) nehmen bei großen Dateien viel Zeit in Anspruch. SiegeX und ghostdog74 haben zwei großartige awk-Methoden zum Extrahieren von Zeilen verwendet, die nur für eine von zwei Dateien im Stapelüberlauf gelten:
quelle
Wenn die Dateien groß sind und Sie keine benutzerdefinierte Reihenfolge für Ihre Einträge haben, dauert grep viel zu lange. Eine schnelle Alternative wäre
[file2-file1 führt zum Screen, Pipe zur Datei usw.]
Ändern
>
zu<
würde die entgegengesetzte Subtraktion erhalten.rm 1 2
quelle
Sie können auch vimdiff in Betracht ziehen, um die Unterschiede zwischen Dateien in einem vim-Editor hervorzuheben
quelle