Wenn Sie Daten aus zwei Textdateien kombinieren möchten, indem Sie nach einem gemeinsamen Datenfeld suchen, ist der Linux-Befehl `join` ein nützliches Werkzeug. Er verleiht Ihren statischen Datensätzen eine gewisse Dynamik. Wir zeigen Ihnen, wie Sie ihn verwenden können.
Daten aus verschiedenen Quellen zusammenführen
Daten sind von entscheidender Bedeutung. Sie sind die Grundlage für Konzerne, Unternehmen und Privathaushalte gleichermaßen. Allerdings sind Daten, die in unterschiedlichen Dateien gespeichert und von verschiedenen Personen zusammengestellt wurden, oft schwierig zu handhaben. Neben dem Problem, die richtigen Dateien zu finden, unterscheiden sich diese wahrscheinlich auch in Format und Struktur.
Zusätzlich müssen Sie sich mit administrativen Herausforderungen auseinandersetzen, z.B. welche Dateien aktualisiert, gesichert, archiviert oder als veraltet betrachtet werden müssen.
Wenn Sie Ihre Daten zusammenführen oder umfassende Analysen durchführen müssen, kommt ein weiteres Problem hinzu: Wie lassen sich die Daten aus den unterschiedlichen Dateien so aufbereiten, dass sie für Ihre Zwecke nutzbar sind? Wie gestalten Sie die Datenvorbereitungsphase?
Die gute Nachricht ist: Der Linux-Befehl `join` kann Ihnen helfen, wenn die Dateien mindestens ein gemeinsames Datenelement haben.
Die Datenbestände
Um die Verwendung des `join`-Befehls zu demonstrieren, verwenden wir fiktive Daten in zwei Dateien:
cat file-1.txt
cat file-2.txt
Hier ist der Inhalt von `file-1.txt`:
1 Adore Varian [email protected] Female 192.57.150.231 2 Nancee Merrell [email protected] Female 22.198.121.181 3 Herta Friett [email protected] Female 33.167.32.89 4 Torie Venmore [email protected] Female 251.9.204.115 5 Deni Sealeaf [email protected] Female 210.53.81.212 6 Fidel Bezley [email protected] Male 72.173.218.75 7 Ulrikaumeko Standen [email protected] Female 4.204.0.237 8 Odell Jursch [email protected] Male 1.138.85.117
Jede Zeile ist nummeriert und enthält:
- Eine Zahl
- Einen Vornamen
- Einen Nachnamen
- Eine E-Mail-Adresse
- Das Geschlecht
- Eine IP-Adresse
Hier ist der Inhalt von `file-2.txt`:
1 Varian [email protected] Female Western New York $535,304.73 2 Merrell [email protected] Female Finger Lakes $309,033.10 3 Friett [email protected] Female Southern Tier $461,664.44 4 Venmore [email protected] Female Central New York $175,818.02 5 Sealeaf [email protected] Female North Country $126,690.15 6 Bezley [email protected] Male Mohawk Valley $366,733.78 7 Standen [email protected] Female Capital District $674,634.93 8 Jursch [email protected] Male Hudson Valley $663,821.09
Jede Zeile in `file-2.txt` enthält:
- Eine Zahl
- Einen Nachnamen
- Eine E-Mail-Adresse
- Das Geschlecht
- Eine Region in New York
- Einen Geldbetrag
Der Befehl `join` arbeitet mit „Feldern“, d.h. Textabschnitten, die durch Leerzeichen begrenzt sind, oder dem Zeilenanfang bzw. -ende. Um Zeilen aus beiden Dateien abzugleichen, muss jede Zeile ein gemeinsames Feld enthalten.
Wir können nur Felder abgleichen, die in beiden Dateien vorkommen. Die IP-Adresse ist z.B. nur in einer Datei vorhanden, also nicht brauchbar. Der Vorname ist ebenfalls nicht geeignet, da er nur in einer Datei vorkommt. Der Nachname kommt zwar in beiden Dateien vor, wäre aber keine gute Wahl, da verschiedene Personen denselben Nachnamen haben könnten.
Ebenso können wir keine Daten über die männlichen und weiblichen Einträge zusammenführen, da sie zu ungenau sind. Die Regionen von New York und die Geldbeträge sind ebenfalls nur in einer Datei enthalten.
Wir können jedoch die E-Mail-Adresse verwenden, da diese in beiden Dateien vorhanden und für jede Person eindeutig ist. Ein kurzer Blick in die Dateien bestätigt auch, dass die Zeilen in jeder Datei derselben Person entsprechen. Daher können wir die Zeilennummern als passendes Feld verwenden (wir werden später ein anderes Feld verwenden).
Beachten Sie, dass die Dateien eine unterschiedliche Anzahl von Feldern haben können, was kein Problem ist – wir können `join` mitteilen, welches Feld aus welcher Datei verwendet werden soll.
Vorsicht bei Feldern wie den Regionen von New York; in einer durch Leerzeichen getrennten Datei wird jedes Wort eines Regionsnamens als Feld betrachtet. Da einige Regionen aus zwei oder drei Wörtern bestehen, kann die Anzahl der Felder in der Datei variieren. Das ist aber kein Problem, solange Sie Felder vor den Regionsnamen abgleichen.
Der Befehl `join`
Zunächst muss das Feld, das abgeglichen werden soll, sortiert sein. In beiden Dateien sind die Nummern aufsteigend, also erfüllen wir diese Bedingung. Standardmäßig verwendet `join` das erste Feld einer Datei. Das ist in unserem Fall auch so gewünscht. Eine weitere Standardeinstellung ist, dass `join` Leerzeichen als Feldtrennzeichen erwartet. Das trifft auch zu. Also können wir direkt loslegen.
Da wir die Standardeinstellungen verwenden, ist der Befehl einfach:
join file-1.txt file-2.txt
`join` betrachtet die Dateien als „Datei eins“ und „Datei zwei“, entsprechend der Reihenfolge in der Befehlszeile.
Die Ausgabe sieht so aus:
1 Adore Varian [email protected] Female 192.57.150.231 Varian [email protected] Female Western New York $535,304.73 2 Nancee Merrell [email protected] Female 22.198.121.181 Merrell [email protected] Female Finger Lakes $309,033.10 3 Herta Friett [email protected] Female 33.167.32.89 Friett [email protected] Female Southern Tier $461,664.44 4 Torie Venmore [email protected] Female 251.9.204.115 Venmore [email protected] Female Central New York $175,818.02 5 Deni Sealeaf [email protected] Female 210.53.81.212 Sealeaf [email protected] Female North Country $126,690.15 6 Fidel Bezley [email protected] Male 72.173.218.75 Bezley [email protected] Male Mohawk Valley $366,733.78 7 Ulrikaumeko Standen [email protected] Female 4.204.0.237 Standen [email protected] Female Capital District $674,634.93 8 Odell Jursch [email protected] Male 1.138.85.117 Jursch [email protected] Male Hudson Valley $663,821.09
Die Ausgabe ist wie folgt formatiert: Das Feld, nach dem die Zeilen abgeglichen wurden, wird zuerst ausgegeben, gefolgt von den Feldern aus Datei eins und dann den Feldern aus Datei zwei, ohne das Match-Feld.
Unsortierte Felder
Testen wir etwas, von dem wir wissen, dass es nicht funktionieren wird. Wir bringen die Zeilen in einer Datei in die falsche Reihenfolge, so dass `join` die Datei nicht richtig verarbeiten kann. Der Inhalt von `file-3.txt` ist derselbe wie in `file-2.txt`, aber Zeile acht befindet sich zwischen den Zeilen fünf und sechs.
Das ist der Inhalt von `file-3.txt`:
1 Varian [email protected] Female Western New York $535,304.73 2 Merrell [email protected] Female Finger Lakes $309,033.10 3 Friett [email protected] Female Southern Tier $461,664.44 4 Venmore [email protected] Female Central New York $175,818.02 5 Sealeaf [email protected] Female North Country $126,690.15 8 Jursch [email protected] Male Hudson Valley $663,821.09 6 Bezley [email protected] Male Mohawk Valley $366,733.78 7 Standen [email protected] Female Capital District $674,634.93
Wir geben folgenden Befehl ein, um zu versuchen, `file-3.txt` mit `file-1.txt` zu verbinden:
join file-1.txt file-3.txt
`join` meldet, dass die siebte Zeile in `file-3.txt` nicht in Ordnung ist und deshalb nicht verarbeitet wird. Zeile sieben ist die, die mit der Zahl sechs beginnt. In einer richtig sortierten Liste sollte diese vor der Acht kommen. Die sechste Zeile in der Datei (die mit „8 Odell“ beginnt) wurde zuletzt verarbeitet, daher sehen wir deren Ausgabe.
Sie können die Option `–check-order` verwenden, um zu überprüfen, ob `join` mit der Sortierreihenfolge einer Datei zufrieden ist. Es wird keine Zusammenführung versucht.
Geben Sie dafür Folgendes ein:
join --check-order file-1.txt file-3.txt
`join` informiert Sie vorab darüber, dass es ein Problem mit Zeile sieben in Datei `file-3.txt` gibt.
Dateien mit fehlenden Zeilen
In `file-4.txt` wurde die letzte Zeile entfernt, d.h. es gibt keine Zeile acht. Der Inhalt ist folgendermaßen:
1 Varian [email protected] Female Western New York $535,304.73 2 Merrell [email protected] Female Finger Lakes $309,033.10 3 Friett [email protected] Female Southern Tier $461,664.44 4 Venmore [email protected] Female Central New York $175,818.02 5 Sealeaf [email protected] Female North Country $126,690.15 6 Bezley [email protected] Male Mohawk Valley $366,733.78 7 Standen [email protected] Female Capital District $674,634.93
Wir geben Folgendes ein, und überraschenderweise beschwert sich `join` nicht und verarbeitet alle Zeilen, die es kann:
join file-1.txt file-4.txt
Die Ausgabe listet sieben verbundene Zeilen auf.
Die Option `-a` (print unpairable) weist `join` an, auch die Zeilen auszugeben, die nicht übereinstimmen konnten.
Geben Sie den folgenden Befehl ein, um `join` anzuweisen, die Zeilen aus Datei eins auszugeben, die nicht mit Zeilen in Datei zwei abgeglichen werden können:
join -a 1 file-1.txt file-4.txt
Sieben Zeilen werden abgeglichen, und Zeile 8 aus Datei 1 wird ohne Übereinstimmung ausgegeben. Es gibt keine zusammengeführten Informationen, da `file-4.txt` keine Zeile 8 zum Abgleichen hatte. Sie erscheint jedoch immer noch in der Ausgabe, damit Sie sehen können, dass es keine Übereinstimmung in `file-4.txt` gab.
Wir geben den folgenden Befehl `-v` (verknüpfte Zeilen unterdrücken) ein, um alle Zeilen auszugeben, die keine Übereinstimmung haben:
join -v file-1.txt file-4.txt
Wir sehen, dass Zeile acht die einzige ist, die keine Übereinstimmung in Datei zwei hat.
Abgleich mit anderen Feldern
Lassen Sie uns zwei neue Dateien mit einem Feld verbinden, das nicht das Standardfeld ist (Feld eins). Das ist der Inhalt von `file-7.txt`:
[email protected] Female 192.57.150.231 [email protected] Female 210.53.81.212 [email protected] Male 72.173.218.75 [email protected] Female 33.167.32.89 [email protected] Female 22.198.121.181 [email protected] Male 1.138.85.117 [email protected] Female 251.9.204.115 [email protected] Female 4.204.0.237
Und das ist der Inhalt von `file-8.txt`:
Female [email protected] Western New York $535,304.73 Female [email protected] North Country $126,690.15 Male [email protected] Mohawk Valley $366,733.78 Female [email protected] Southern Tier $461,664.44 Female [email protected] Finger Lakes $309,033.10 Male [email protected] Hudson Valley $663,821.09 Female [email protected] Central New York $175,818.02 Female [email protected] Capital District $674,634.93
Das einzig sinnvolle Feld zum Verbinden ist die E-Mail-Adresse, die in der ersten Datei Feld eins ist und in der zweiten Datei Feld zwei. Um dies zu berücksichtigen, können wir die Optionen `-1` (Datei eins Feld) und `-2` (Datei zwei Feld) verwenden. Diesen folgen wir mit einer Zahl, die angibt, welches Feld in jeder Datei zum Verbinden verwendet werden soll.
Geben Sie Folgendes ein, um `join` anzuweisen, das erste Feld in Datei eins und das zweite in Datei zwei zu verwenden:
join -1 1 -2 2 file-7.txt file-8.txt
Die Dateien werden über die E-Mail-Adresse verbunden, die als erstes Feld jeder Zeile in der Ausgabe erscheint.
Verwendung anderer Feldtrennzeichen
Was, wenn Sie Dateien mit Feldern haben, die durch andere Zeichen als Leerzeichen getrennt sind?
Die folgenden beiden Dateien sind durch Kommas getrennt – die einzigen Leerzeichen befinden sich zwischen den Ortsnamen, die aus mehreren Wörtern bestehen:
cat file-5.txt
cat file-6.txt
Wir können `-t` (Trennzeichen) verwenden, um `join` mitzuteilen, welches Zeichen als Feldtrennzeichen fungieren soll. In diesem Fall ist es das Komma, also geben wir folgenden Befehl ein:
join -t, file-5.txt file-6.txt
Alle Zeilen werden abgeglichen, und die Leerzeichen in den Ortsnamen bleiben erhalten.
Groß-/Kleinschreibung ignorieren
Eine andere Datei, `file-9.txt`, ist fast identisch mit `file-8.txt`. Der einzige Unterschied ist, dass einige der E-Mail-Adressen einen Großbuchstaben haben, wie unten zu sehen:
Female [email protected] Western New York $535,304.73 Female [email protected] North Country $126,690.15 Male [email protected] Mohawk Valley $366,733.78 Female [email protected] Southern Tier $461,664.44 Female [email protected] Finger Lakes $309,033.10 Male [email protected] Hudson Valley $663,821.09 Female [email protected] Central New York $175,818.02 Female [email protected] Capital District $674,634.93
Als wir `file-7.txt` und `file-8.txt` zusammenführten, hat alles perfekt funktioniert. Sehen wir, was mit `file-7.txt` und `file-9.txt` passiert.
Wir geben folgenden Befehl ein:
join -1 1 -2 2 file-7.txt file-9.txt
Wir haben nur sechs Zeilen abgeglichen. Die Unterschiede in der Groß- und Kleinschreibung verhinderten, dass die beiden anderen E-Mail-Adressen zusammengeführt wurden.
Wir können jedoch die Option `-i` (Groß-/Kleinschreibung ignorieren) verwenden, um zu erzwingen, dass `join` diese Unterschiede ignoriert und Felder abgleicht, die denselben Text enthalten, unabhängig von der Groß-/Kleinschreibung.
Wir geben folgenden Befehl ein:
join -1 1 -2 2 -i file-7.txt file-9.txt
Alle acht Zeilen werden abgeglichen und erfolgreich verbunden.
Mischen und Anpassen
Mit `join` haben Sie einen wertvollen Helfer im Kampf gegen die umständliche Datenaufbereitung. Vielleicht müssen Sie Daten analysieren oder sie für den Import in ein anderes System vorbereiten.
Ganz gleich, wie die Situation aussieht, Sie werden froh sein, `join` zur Hand zu haben!