Methode 1: Verwenden Sie, was Sie wissen
Da Sie bereits wissen, wie man eine Datei durchläuft, können Sie die Dateien kombinieren und dann die kombinierten Dateien verarbeiten. Der Befehl paste
verbindet zwei Dateien zeilenweise. Es wird ein Tabulator zwischen den Zeilen eingefügt, die aus den beiden Dateien stammen. Bei dieser Lösung wird davon ausgegangen, dass Ihre Dateinamen keine Tabulatoren enthalten. (Sie können das Trennzeichen ändern, müssen jedoch ein Zeichen suchen, das in einem Dateinamen nicht vorhanden ist.)
paste -- "$list1.txt" "list2.txt" |
while IFS=$'\t' read -r file1 file2 rest; do
diff -q -- "$file1" "$file2"
case $? in
0) status='same';;
1) status='different';;
*) status='ERROR';;
esac
echo "$status $file1 $file2"
done
Wenn Sie leere Zeilen überspringen möchten, müssen Sie dies in jeder Datei separat tun, da paste
möglicherweise eine leere Zeile aus einer Datei mit einer nicht leeren Zeile aus einer anderen Datei abgeglichen wird. Mit können Sie grep
die nicht leeren Zeilen filtern.
paste -- <(grep '[^[:space:]]' "$list1.txt") <(grep '[^[:space:]]' "list2.txt") |
while IFS=$'\t' read -r file1 file2 rest; do
…
Beachten Sie, dass bei unterschiedlichen Längen der beiden Dateien eine leere angezeigt wird $file2
(unabhängig davon, welche Liste zuerst beendet wurde).
Methode 2: Schleife über zwei Dateien
Sie können einen Befehl im Zustand der while-Schleife so komplex setzen, wie Sie möchten. Wenn Sie setzen read file1 <&3 && read file2 <&4
, läuft die Schleife so lange, wie beide Dateien eine Zeile zum Lesen haben, dh bis eine Datei leer ist.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
Wenn Sie leere Zeilen überspringen möchten, ist dies etwas komplizierter, da Sie die beiden Dateien unabhängig voneinander überspringen müssen. Die einfache Möglichkeit besteht darin, das Problem in zwei Teile zu unterteilen: Überspringen Sie die Leerzeilen aus einer Datei und verarbeiten Sie die nicht leeren Zeilen. Eine Methode zum Überspringen der Leerzeilen besteht darin, grep
wie oben beschrieben vorzugehen. Achten Sie auf den erforderlichen Abstand zwischen dem <
Umleitungsoperator und dem Operator <(
, der eine Befehlssuspension startet.
while read -u 3 -r file1 && read -u 4 -r file2; do
…
done 3< <(grep '[^[:space:]]' "$list1.txt") 4< <(grep '[^[:space:]]' "list2.txt")
Eine andere Methode besteht darin, eine Funktion zu schreiben, die sich so verhält, read
aber leere Zeilen überspringt. Diese Funktion kann durch Aufrufen read
einer Schleife ausgeführt werden. Es muss keine Funktion sein, aber eine Funktion ist der beste Ansatz, um Ihren Code zu organisieren und weil dieser Code zweimal aufgerufen werden muss. In der Funktion gibt ${!#}
es eine Instanz des bash-Konstrukts, ${!VARIABLE}
das den Wert der Variablen ergibt, deren Name der Wert von ist VARIABLE
. hier ist die Variable die spezielle Variable, #
die die Nummer des Positionsparameters enthält, so ${!#}
wie der letzte Positionsparameter.
function read_nonblank {
while read "$@" &&
[[ ${!#} !~ [^[:space:]] ]]
do :; done
}
while read_nonblank -u 3 -r file1 && read_nonblank -u 4 -r file2; do
…
done 3<list1..txt 4<list2.txt
diff
.