Wie vergleiche ich zwei Dateien mit einem Shell-Skript?

10

Bei zwei Dateien möchte ich ein Shell-Skript schreiben, das jede Zeile aus Datei1 liest und prüft, ob sie in Datei2 vorhanden ist. Wenn eine Zeile nicht gefunden wird, sollten zwei unterschiedliche Dateien ausgegeben und beendet werden. Die Dateien können Wörter, Zahlen oder irgendetwas enthalten. Beispielsweise :

Datei1:

Hi!
1234
5678
1111
hello

Datei2:

1111
5678
1234
Hi!
hello

In diesem Fall sollten zwei Dateien gleich sein. wenn file2 "hallo !!!" Anstelle von "Hallo" sind die Dateien unterschiedlich. Ich benutze Bash-Skript. Wie kann ich das machen. Es ist nicht wichtig, dass ich es in einer verschachtelten Schleife tun muss, aber ich dachte, das ist der einzige Weg. Danke für Ihre Hilfe.

0x0
quelle

Antworten:

9

In Bash:

diff --brief <(sort file1) <(sort file2)
Ignacio Vazquez-Abrams
quelle
Was ist, wenn die Datei eine CSV-Datei ist? würde das Sortieren noch funktionieren?
0x0
sortkümmert sich nicht um den genauen Inhalt, es sei denn, Sie sagen es.
Ignacio Vazquez-Abrams
Ist es möglich herauszufinden, welche Linien sich unterscheiden?
0x0
Entfernen --briefund Hinzufügen von Formatoptionen, z -u.
Ignacio Vazquez-Abrams
10

diffLegt den Exit-Status fest, um anzuzeigen, ob die Dateien identisch sind oder nicht. Der Exit-Status ist in der speziellen Variablen zugänglich $?. Sie können Ignacios Antwort folgendermaßen erweitern:

diff --brief <(sort file1) <(sort file2) >/dev/null
comp_value=$?

if [ $comp_value -eq 1 ]
then
    echo "do something because they're different"
else
    echo "do something because they're identical"
fi
Doug Harris
quelle
3
Sie können einfach if diff ... >/dev/nullauf die Klammern und Variablen verzichten.
Bis auf weiteres angehalten.
1

Füge dies hinzu, weil ich denke, dass [[]] && || Konstrukt ist ziemlich ordentlich:

#!/bin/bash

[[ `diff ${HOME}/file1 ${HOME}/file2` ]] &&  
   (echo "files different") ||
   (echo "files same")
mmrtnt
quelle
1

Sollte auch funktionieren:

comm -3 file1 file2

Ich denke, das sind genug Zeichen für eine Antwort ...

mpez0
quelle
1

Obwohl dies diffeine vollkommen gute Antwort ist, würde ich sie wahrscheinlich cmpstattdessen verwenden, um einen Byte-für-Byte-Vergleich zweier Dateien durchzuführen.

https://linux.die.net/man/1/cmp

Aus diesem Grund hat es den zusätzlichen Vorteil, Binärdateien vergleichen zu können.

if cmp -s "file1" "file2"
then
   echo "The files match"
else
   echo "The files are different"
fi

Ich glaube, es ist schneller als die Verwendung, diffobwohl ich das nicht persönlich getestet habe.

Richard
quelle
Würde der Fall "Dateien sind anders" nicht zuerst gehen? Der if-Test fragt, ob etwas wahr ist, dh ein Rückkehrcode ungleich Null. Wenn die Dateien übereinstimmen, gibt cmp 0 (pro Manpage) zurück. Dies sollte also der zweite Fall sein.
user8162
@ user8162 Was du sagst, macht Sinn, aber ich habe es gerade getestet und das ist der richtige Weg. Ich bin mir nicht sicher, warum das so ist, um ehrlich zu sein.
Richard