Im Grunde möchte ich also zwei Dateien zeilenweise in Spalte 2 vergleichen. Wie könnte ich das erreichen?
Datei_1.txt:
User1 US
User2 US
User3 US
Datei_2.txt:
User1 US
User2 US
User3 NG
Ausgabedatei:
User3 has changed
command-line
text-processing
Roboman1723
quelle
quelle
diff "File_1.txt" "File_2.txt"
Antworten:
Schau in den
diff
Befehl. Es ist ein gutes Werkzeug und Sie können alles darüber lesen, indem Sieman diff
in Ihr Terminal tippen.Der Befehl, den Sie ausführen möchten, gibt
diff File_1.txt File_2.txt
den Unterschied zwischen den beiden aus und sollte ungefähr so aussehen:Ein kurzer Hinweis zum Lesen der Ausgabe des dritten Befehls: Die Pfeile (
<
und>
) verweisen auf den Wert der Zeile in der linken Datei (<
) gegenüber der rechten Datei (>
), wobei die linke Datei die von Ihnen eingegebene ist in diesem Fall zuerst in der BefehlszeileFile_1.txt
Außerdem stellen Sie möglicherweise fest, dass der vierte Befehl darin besteht,
diff ... | tee Output_File
die Ergebnisse vondiff
in ein zutee
leiten, wodurch diese Ausgabe in eine Datei verschoben wird , sodass Sie sie für einen späteren Zeitpunkt speichern können, wenn Sie nicht alles in dieser Sekunde auf der Konsole anzeigen möchten.quelle
diff file1 file2 -s
. Hier ist ein Beispiel: imgur.com/ShrQx9xOder Sie können Meld Diff verwenden
Installieren Sie, indem Sie Folgendes ausführen:
Ihr Beispiel:
Verzeichnis vergleichen:
Beispiel mit vollem Text:
quelle
Sie können vimdiff verwenden .
Beispiel:
quelle
dos
und die zweite in warunix
.FWIW, ich mag eher, was ich mit Side-by-Side-Ausgabe von diff bekomme
würde etwas geben wie:
quelle
Sie können den Befehl verwenden
cmp
:Ausgabe wäre
quelle
cmp
ist viel schneller alsdiff
wenn alles was Sie wollen, der Rückkehrcode ist.Meld
ist ein wirklich tolles Werkzeug. Sie können aber auchdiffuse
zwei Dateien visuell vergleichen:quelle
Wenn Sie sich an die Frage halten (Datei1, Datei2, Ausgabedatei mit der Meldung "Hat sich geändert"), funktioniert das folgende Skript.
Kopieren Sie das Skript in eine leere Datei, speichern Sie es als
compare.py
, machen Sie es ausführbar und führen Sie es mit dem folgenden Befehl aus:Das Drehbuch:
Mit ein paar zusätzlichen Zeilen können Sie es entweder in eine Ausgabedatei oder auf das Terminal drucken lassen, je nachdem, ob die Ausgabedatei definiert ist:
So drucken Sie in eine Datei:
So drucken Sie in das Terminalfenster:
Das Drehbuch:
quelle
Eine einfache Möglichkeit ist die Verwendung
colordiff
, die sich so verhält,diff
aber die Ausgabe einfärbt. Dies ist sehr hilfreich zum Lesen von Unterschieden. Verwenden Sie Ihr Beispiel,Wobei die
u
Option ein einheitliches Diff ergibt. So sieht das eingefärbte Diff aus:Installieren Sie
colordiff
durch Ausführensudo apt-get install colordiff
.quelle
Zusätzliche Antwort
Wenn Sie nicht wissen müssen, welche Teile der Dateien unterschiedlich sind, können Sie die Prüfsumme der Datei verwenden. Es gibt viele Möglichkeiten, dies mit
md5sum
oder zu tunsha256sum
. Grundsätzlich gibt jeder von ihnen eine Zeichenfolge aus, zu der ein Dateiinhalt-Hash gehört. Wenn die beiden Dateien identisch sind, ist auch der Hash identisch. Dies wird häufig verwendet, wenn Sie Software herunterladen, z. B. Ubuntu-Installations-ISO-Images. Sie werden häufig zur Überprüfung der Integrität eines heruntergeladenen Inhalts verwendet.Betrachten Sie das folgende Skript, in dem Sie zwei Dateien als Argumente angeben können. In der Datei wird angegeben, ob sie identisch sind oder nicht.
Probelauf:
Ältere Antwort
Zusätzlich gibt es einen
comm
Befehl, der zwei sortierte Dateien vergleicht und die Ausgabe in 3 Spalten liefert: Spalte 1 für Elemente, die nur in Datei 1 vorhanden sind, Spalte 2 für Elemente, die nur in Datei 2 vorhanden sind, und Spalte 3 für Elemente, die in beiden Dateien vorhanden sind.Zum Unterdrücken einer Spalte können Sie die Schalter -1, -2 und -3 verwenden. Mit -3 werden die Zeilen angezeigt, die sich unterscheiden.
Unten sehen Sie den Screenshot des Befehls in Aktion.
Es gibt nur eine Anforderung: Die Dateien müssen sortiert sein, damit sie richtig verglichen werden können.
sort
Befehl kann für diesen Zweck verwendet werden. Unten sehen Sie einen weiteren Screenshot, in dem Dateien sortiert und dann verglichen werden. Zeilen, die links beginnen, gehören nur zu File_1, Zeilen, die in Spalte 2 beginnen, gehören nur zu File_2quelle
Installieren Sie Git und verwenden Sie
Und Sie erhalten eine Ausgabe in schönen Farben
Git- Installation
quelle
colcmp.sh
Vergleicht Name / Wert-Paare in 2 Dateien im Format
name value\n
. Schreibt dasname
zu,Output_file
wenn es geändert wird. Benötigt bash v4 + für assoziative Arrays .Verwendungszweck
Ausgabedatei
Quelle (colcmp.sh)
Erläuterung
Aufschlüsselung des Codes und was er bedeutet, nach bestem Wissen. Ich freue mich über Änderungen und Vorschläge.
Basic File Compare
cmp setzt den Wert von $? wie folgt :
Ich habe mich für eine case .. esac- Anweisung entschieden, um $ auszuwerten . weil der Wert von $? ändert sich nach jedem Befehl, einschließlich test ([).
Alternativ könnte ich eine Variable verwendet haben, um den Wert von $ zu halten ? :
Oben wird dasselbe wie in der case-Anweisung gemacht. IDK was mir besser gefällt.
Löschen Sie die Ausgabe
Oben wird die Ausgabedatei gelöscht. Wenn also keine Benutzer geändert wurden, ist die Ausgabedatei leer.
Ich mache dies in den case- Anweisungen, damit die Output_file im Fehlerfall unverändert bleibt.
Kopieren Sie die Benutzerdatei in das Shell-Skript
Oben kopiert File_1.txt in das Ausgangsverzeichnis des aktuellen Benutzers.
Wenn der aktuelle Benutzer beispielsweise john ist, ist das oben Genannte dasselbe wie cp "File_1.txt" /home/john/.colcmp.arrays.tmp.sh
Sonderzeichen entkommen
Grundsätzlich bin ich paranoid. Ich weiß, dass diese Zeichen eine besondere Bedeutung haben oder ein externes Programm ausführen können, wenn sie in einem Skript als Teil der Variablenzuweisung ausgeführt werden:
Was ich nicht weiß, ist, wie viel ich nicht über Bash weiß. Ich weiß nicht, welche anderen Zeichen eine besondere Bedeutung haben könnten, aber ich möchte sie alle mit einem Backslash umgehen:
sed kann viel mehr als nur den Mustervergleich mit regulären Ausdrücken . Das Skriptmuster "s / (find) / (replace) /" führt speziell die Musterübereinstimmung durch.
"s / (find) / (replace) / (modifiers)"
in englischer Sprache: Zeichensetzung oder Sonderzeichen als Erfassungsgruppe 1 erfassen (\\ 1)
auf englisch: allen Sonderzeichen einen Backslash voranstellen
auf englisch: wenn mehr als eine Übereinstimmung in derselben Zeile gefunden wird, ersetzen Sie sie alle
Kommentieren Sie das gesamte Skript aus
Oben wird ein regulärer Ausdruck verwendet, um jeder Zeile von ~ / .colcmp.arrays.tmp.sh ein Bash-Kommentarzeichen ( # ) voranzustellen . Ich mache das, weil ich später vorhabe, ~ / .colcmp.arrays.tmp.sh mit dem Befehl source auszuführen, und weil ich das gesamte Format von nicht genau kenne File_1.txt kenne .
Ich möchte nicht versehentlich beliebigen Code ausführen. Ich glaube nicht, dass jemand das tut.
s / (find) / (replace) /
in Englisch: Erfassen Sie jede Zeile als Erfassungsgruppe 1 (\\ 1)
in englischer sprache: ersetzen sie jede zeile durch ein rautenzeichen, gefolgt von der zeile, die ersetzt wurde
Benutzerwert in A1 konvertieren [User] = "value"
Oben ist der Kern dieses Skripts.
#User1 US
A1[User1]="US"
A2[User1]="US"
(für die 2. Datei)s / (find) / (replace) /
auf Englisch:
Erfassen Sie den Rest der Zeile als Erfassungsgruppe 2
(Ersetzen) = A1 \\ [\\ 1 \\] = \ "\\ 2 \"
A1[
zum Starten der Arrayzuweisung in einem aufgerufenen ArrayA1
]="
]
= naheA1[
Arrayzuordnung zB User1]="
US"
=
= Zuweisungsoperator zB Variable = Wert"
= Anführungszeichen, um Leerzeichen zu erfassen ... obwohl es jetzt, wo ich darüber nachdenke, einfacher gewesen wäre, den Code über diesem Backslash alles in Backslash-Leerzeichen umzuwandeln.auf Englisch: Ersetzen Sie jede Zeile im Format
#name value
durch einen Array-Zuweisungsoperator im FormatA1[name]="value"
Ausführbar machen
Oben wird chmod verwendet , um die Array-Skriptdatei ausführbar zu machen.
Ich bin mir nicht sicher, ob das notwendig ist.
Assoziatives Array deklarieren (bash v4 +)
Das Großbuchstaben -A gibt an, dass die deklarierten Variablen assoziative Arrays sind .
Aus diesem Grund benötigt das Skript bash v4 oder höher.
Führen Sie unser Array-Variablenzuweisungsskript aus
Wir haben schon:
User value
zu Zeilen vonA1[User]="value"
,Oben haben wir beziehen das Skript es in dem aktuell Shell ausgeführt werden . Wir tun dies, um die vom Skript gesetzten Variablenwerte beizubehalten. Wenn Sie das Skript direkt ausführen, wird eine neue Shell erstellt, und die Variablenwerte gehen verloren, wenn die neue Shell beendet wird.
Dies sollte eine Funktion sein
Wir machen dasselbe für $ 1 und A1 wie für $ 2 und A2 . Es sollte wirklich eine Funktion sein. Ich denke, an diesem Punkt ist dieses Skript verwirrend genug und es funktioniert, also werde ich es nicht reparieren.
Entfernte Benutzer erkennen
Oben werden assoziative Array-Schlüssel durchlaufen
Oben wird die Variablensubstitution verwendet, um den Unterschied zwischen einem nicht festgelegten Wert und einer Variablen zu ermitteln, die explizit auf eine Zeichenfolge der Länge Null festgelegt wurde.
Anscheinend gibt es viele Möglichkeiten, um festzustellen, ob eine Variable festgelegt wurde . Ich habe den mit den meisten Stimmen gewählt.
Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt
Erkennen Sie hinzugefügte oder geänderte Benutzer
Oben wird eine Variable gelöscht, damit wir die Benutzer verfolgen können, die sich nicht geändert haben.
Oben werden assoziative Array-Schlüssel durchlaufen
Oben wird die Variablensubstitution verwendet, um festzustellen, ob eine Variable festgelegt wurde .
Da $ i der Array-Schlüssel (Benutzername) ist, sollte $ A2 [$ i] den Wert zurückgeben, der dem aktuellen Benutzer aus File_2.txt zugeordnet ist .
Wenn zum Beispiel $ i ist User1 , die oben lautet wie $ {A2 [User1]}
Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt
Da $ i der Array-Schlüssel (Benutzername) ist, sollte $ A1 [$ i] den dem aktuellen Benutzer zugeordneten Wert aus File_1.txt und $ A2 [$ i] den Wert aus File_2.txt zurückgeben .
Oben werden die zugehörigen Werte für Benutzer $ i aus beiden Dateien verglichen .
Oben wird der Benutzer $ i zur Ausgabedatei hinzugefügt
Oben wird eine durch Kommas getrennte Liste von Benutzern erstellt, die sich nicht geändert haben. Beachten Sie, dass die Liste keine Leerzeichen enthält. Andernfalls muss der nächste Scheck in Anführungszeichen gesetzt werden.
Oben wird der Wert von $ USERSWHODIDNOTCHANGE gemeldet, jedoch nur, wenn $ USERSWHODIDNOTCHANGE einen Wert enthält . So wie dies geschrieben ist, darf $ USERSWHODIDNOTCHANGE keine Leerzeichen enthalten. Wenn Leerzeichen erforderlich sind, könnte dies wie folgt geändert werden:
quelle