Grundsätzlich müssen Sie zwei Dateien vergleichen und das nachfolgende Byte unter bestimmten Bedingungen ignorieren. Es gibt keine "diff" -Option, aber es gibt eine Reihe von Möglichkeiten, wie dies gemacht werden kann (z. B. kommt auch hex diff in den Sinn).
Um 'diff' zu verwenden, müssen Sie im Grunde genommen die Dateien ändern, denen die Zeilenumbruchzeile am Ende einer Datei fehlt, und dann vergleichen. Sie können ein temporäres Verzeichnis mit den geänderten Dateien erstellen oder mit ein wenig Skripting im Speicher ausführen. (Was bevorzugt wird, hängt von der Präferenz, der Dateigröße, der Anzahl der Dateien ... ab.)
Beispiel: Der folgende Befehl ändert den Inhalt einer Datei (wird verwendet sed -i
, um sie an Ort und Stelle zu ändern. Dies wird nur auf stdout gedruckt.), Um eine neue Zeile hinzuzufügen, falls eine fehlt (oder die Datei unverändert zu lassen, falls bereits eine neue Zeile vorhanden ist):
sed -e '$a\' file1.txt
Und nur um die 'diff'-Syntax zu überprüfen (true bedeutet, dass sie gleich sind, false bedeutet anders):
$ diff a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
2c2
< eof
---
> eof
\ No newline at end of file
** are different
Stellen Sie sicher, dass nur Leerzeichen unterschiedlich sind:
$ diff --ignore-all-space a/file1.txt b/file1.txt \
&& echo '** are same' || echo '** are different'
** are same
In bash können wir 'sed' verwenden, um den Dateiinhalt so zu bearbeiten, wie er an 'diff' übergeben wird (Originaldateien bleiben unverändert):
$ diff <(sed -e '$a\' a/file1.txt) <(sed -e '$a\' b/file1.txt) \
&& echo '** are same' || echo '** are different'
** are same
Jetzt müssen Sie nur noch emulieren diff -r
, um Verzeichnisse rekursiv zu vergleichen. Wenn Sie Verzeichnisse a
und vergleichen b
, leiten Sie für alle Dateien in a
(z. B. a/dir1/dir2/file.txt
) den Pfad zur Datei in b
(z. B. b/dir1/dir2/file.txt
) ab und vergleichen Sie:
$ for f in $( find a -type f )
> do
> diff <(sed -e '$a\' $f) <(sed -e '$a\' b/${f#*/})
> done
Eine etwas ausführlichere Version:
$ for f in $( find a -type f )
> do
> f1=$f
> f2=b/${f#*/}
> echo "compare: $f1 $f2"
> diff <(sed -e '$a\' $f1) <(sed -e '$a\' $f2) \
> && echo '** are same' || echo '** are different'
> done && echo '** all are same' || echo '** all are different'
compare: a/file1.txt b/file1.txt
** are same
compare: a/file2.txt b/file2.txt
** are same
** all are same
sed -e '$a\'
genau funktioniert? thxsed
mit dem folgenden (-e
) Skript / Ausdruck aus, der mit dem Ende der Datei ($
) übereinstimmt , und führen Sie die Aktion "Anhängen" (a \) aus, geben Sie jedoch keinen Text an (nichts nach dem `\`) wird weiterhin eine EOF / Newline am Ende der Datei einfügen (nur wenn diese fehlt).a\
.Ich habe das Problem gelöst, indem ich jeder Datei eine neue Zeile hinzugefügt und leere Zeilen im Diff ignoriert habe (Option
-B
). Diese Lösung ist möglicherweise nicht für Ihren Anwendungsfall geeignet, kann jedoch anderen helfen:quelle
Leiten Sie die Ausgabe von
diff
an einengrep
Befehl weiter, der die Nachricht löscht, die Sie nicht sehen möchten.quelle
Ich habe mir auch einen anderen Ansatz überlegt, der für größere Dateien funktioniert (und die Originaldateien immer noch nicht kopiert oder modifiziert). Sie müssten immer noch die rekursive Verzeichnisdurchquerung emulieren (und es gibt eine Reihe von Möglichkeiten, dies zu tun), aber in diesem Beispiel wird nicht "sed" verwendet, sondern nur zwei Dateien ohne das letzte Byte verglichen
cmp
, z.Durchlaufen Sie weiterhin alle Dateien im Verzeichnis, und berechnen Sie für zwei Dateien a / file.txt und b / file.txt die größere Dateigröße, subtrahieren Sie eine und führen Sie dann ein binäres diff (
cmp
) mit dieser Anzahl von Bytes aus (ebenfalls in) bash):Das Durchlaufen der Dateien erfolgt wie in der anderen Antwort mit
sed
unddiff
.quelle
Die Antwort ist einfach.
Die Meldung über den fehlenden Zeilenumbruch befindet sich nicht im Ausgabestream von,
diff
sondern im Fehlerstrom. Biege es also zum Nirvana und du bist für immer fertigquelle
In diff befindet sich eine Flagge
--strip-trailing-cr
, die genau das tut, wonach Sie gefragt habenquelle
/r/n
wie/n
und hat nichts mit extra/n
kurz vor EOF zu tun .