Mit dem Programm join können Daten aus zwei Dateien verknüpft werden. Dabei werden Zeilen mit gleichen Daten in einem bestimmten Feld zusammengefügt. Das Ganze funktioniert also ähnlich wie ein SQL-JOIN.
Ähnlich wie bei anderen Tools müssen die Daten bereits sortiert sein. Hierbei hilft wie immer sort. Außerdem arbeitet join auch mit Feldern, die durch ein Trennzeichen getrennt sind.
Ein kurzes Beispiel mit einfachen Testdaten. Datei1:
1 jan
2 feb
3 mar
5 may
Datei2:
1 31
2 28
3 31
4 30
Ein Join aus beiden Dateien:
$ join Datei1 Datei2
1 jan 31
2 feb 28
3 mar 31
Standardmäßig wird das Feld 1 aus beiden Dateien verglichen. Möglich ist auch, unterschiedliche Felder zu nehmen. Dafür gibt die es Optionen -1 <feldnummer>
, um die Feldnummer für die erste Datei anzugeben. Für die zweite Datei gibt es die Option -2 <feldnummer>
. Ebenso ist es möglich, statt Space ein anderes Trennzeichen mit der Option -t <char>
anzugeben.
In der Ausgabe dürfte einem auffallen, dass Zeilen, die nicht verbunden werden können, nicht ausgegeben werden (INNER JOIN). Dies lässt sich mit den Optionen -a1
und -a2
ändern. Wenn -a1
angegeben ist, werden von der ersten Datei alle Zeilen ausgegeben, bei -a2
das gleiche für die zweite Datei. Es können auch beide Optionen benutzt werden.
Das war jetzt nur eine einfache 1:1-Beziehung. Mit join funktionieren aber auch 1:n-Beziehungen. Nehmen wir dafür ein paar neue Beispieldaten:
Datei1:
admin 1000 System Administrator
max 1001 Max Mustermann
john 1002 John Doe
Datei2:
max user 20 11. Dez 18:01 report.pdf
max user 12 11. Dez 17:56 calc.txt
admin admin 78 8. Dez 10:52 list.txt
john user 24 18. Dez 17:22 stuff1
john user 20 18. Dez 17:22 stuff2
max user 12 11. Dez 18:09 newfile1.txt
max user 10 11. Dez 18:09 todo.txt
admin admin 109 8. Dez 11:28 machines.txt
john user 58 25. Nov 07:26 names.txt
john user 42 25. Nov 07:27 states.txt
admin admin 152 7. Dez 17:42 table1
max user 25 8. Dez 10:12 testdata
max user 12 11. Dez 18:08 test.txt
Join:
$ join <(sort Datei1) <(sort Datei2)
admin 1000 System Administrator admin 109 8. Dez 11:28 machines.txt
admin 1000 System Administrator admin 152 7. Dez 17:42 table1
admin 1000 System Administrator admin 78 8. Dez 10:52 list.txt
john 1002 John Doe user 20 18. Dez 17:22 stuff2
john 1002 John Doe user 24 18. Dez 17:22 stuff1
john 1002 John Doe user 42 25. Nov 07:27 states.txt
john 1002 John Doe user 58 25. Nov 07:26 names.txt
max 1001 Max Mustermann user 10 11. Dez 18:09 todo.txt
max 1001 Max Mustermann user 12 11. Dez 17:56 calc.txt
max 1001 Max Mustermann user 12 11. Dez 18:08 test.txt
max 1001 Max Mustermann user 12 11. Dez 18:09 newfile1.txt
max 1001 Max Mustermann user 20 11. Dez 18:01 report.pdf
max 1001 Max Mustermann user 25 8. Dez 10:12 testdata
Funktioniert also auch hier wie in SQL. Da wir pro Zeile in Datei1 mehrere Zeilen in Datei2 haben, werden die Zeilen in Datei1 dupliziert.
Mit dem Programm comm können Dateien miteinander verglichen werden. Das Programm prüft, ob Zeilen in Datei1, in Datei2 oder in beiden vorhanden sind. Die Daten müssen hierfür bereits sortiert sein. Falls dies nicht der Fall ist, hilft wieder sort.
Hier ein einfaches Beispiel zu comm:
$ cat > file1
1
2
3
a
b
c
$ cat > file2
0
1
b
c
d
$ comm file1 file2
0
1
2
3
a
b
c
d
Die Ausgabe enthält 3 Spalten:
- Spalte 1: Zeilen, die nur in file1 sind
- Spalte 2: Zeilen, die nur in file2 sind
- Spalte 3: Zeilen, die in beiden Dateien vorhanden sind
Um die Ausgabe zu filtern, gibt es die Optionen -1 -2 und -3 um die jeweiligen Spalten bei der Ausgabe zu unterdrücken. Um z.B. nur die Spalte 3 auszugeben, muss -12 angegeben werden:
$ comm -12 file1 file2
1
b
c
Damit kann comm genutzt werden, um Schnittmengen oder Differenzmengen zu bilden.
Die klassische Unix-Rechteverwaltung dürfte den meisten ein Begriff sein. Es gibt drei Arten von Zugriffsrechten: read, write und execute. Für jede Datei sind diese Rechte jeweils für den User, die Group und Other gesetzt. Macht insgesammt 9 Bits, es gibt jedoch noch drei weitere Bits, nämlich für setuid, setgid und das sticky bit. Die Bedeutung dieser zusätzlichen Rechte hängt teilweise davon ab, um was für eine Art Datei es sich handelt.
setuid
Wenn das setuid-Bit für Executables gesetzt ist, dann wird das Programm mit den Rechten des Dateieigentümers ausgeführt. Dies ist zum Beispiel nötig für su
, welches Root-Rechte für seine Funkion benötigt.
setgid
Bei Executables bewirkt das setgid-Bit, ähnlich wie bei setuid, dass Programme die Gruppenrechte des Eigentümers beim Ausführen erhalten.
Das setgid-Bit kann jedoch auch für Verzeichnisse gesetzt werden. Dies bewirkt, dass Dateien, die in diesem Verzeichnis erstellt werden, die Gruppe des Verzeichnisses erhalten, und nicht die Gruppe des Benutzers, der die Datei erstellt.
Sticky Bit
Das Sticky Bit kann auf Verzeichnissen angewendet werden und bewirkt bei diesen, dass die dort enthaltenen Dateien nur von ihrem Besitzer gelöscht werden können. Dies ist sinnvoll bei Verzeichnissen, auf die mehrere Benutzer vollen Zugriff haben, denn ohne Sticky Bit kann jeder enthaltene Dateien löschen.
Beispiel: chmod und ls
Erstellen wir kurz eine Datei:
$ touch file
$ ls -l
total 0
-rw-r--r-- 1 olaf user 0 Apr 22 12:51 file
setuid:
$ chmod u+s file
$ ls -l
total 0
-rwSr--r-- 1 olaf user 0 Apr 22 12:51 file
setgid:
$ chmod g+s file
$ ls -l
total 0
-rwSr-Sr-- 1 olaf user 0 Apr 22 12:51 file
Sticky Bit:
$ mkdir dir
$ ls -l
total 4
drwxr-xr-x 2 olaf user 4096 Apr 22 12:53 dir
-rwSr-Sr-- 1 olaf user 0 Apr 22 12:51 file
$ chmod +t dir
$ ls -l
total 4
drwxr-xr-t 2 olaf user 4096 Apr 22 12:53 dir
-rwSr-Sr-- 1 olaf user 0 Apr 22 12:51 file
Eine tar-Datei besteht immer aus 512 Bytes großen Blöcken. Jede Datei im Archiv hat einen Header-Block gefolgt von weiteren Blöcken für den Dateiinhalt. Verzeichnisse oder Links haben logischerweise keine Content-Blöcke sondern nur den Header-Block. Am Ende des Archivs werden dann zwei 512 Bytes Blöcke mit Null-Bytes angehängt, die das Ende markieren.
Der Header besteht fast nur aus Plain-Text, nur ein paar Null-Bytes kommen vor. Integer-Werte werden als Oktal-Strings gespeichert. Auch sind alle Felder des Headers an fixen Adressen, was das parsen vereinfacht. Eine Beschreibung des Headers findet sich auf der Open Group Webseite.
Da der Header nur begrenzt viel Platz hat, hat das Original UStar-Format (Unix Standard TAR) ein paar Limitierungen. Z.B. können Dateinamen oder Pfade nicht beliebig lang sein. Auch die Größe einzelner Dateien ist durch die spezielle Kodierung auf 8 Gb begrenzt. Erweiterungen dieses Formats, wie das neue POSIX Format pax oder auch GNU tar und star, haben diese Begrenzung nicht.
Wer tar-Dateien im alten UStar-Format in seinem eigenen Programm erstellen will, für den habe ich dieses Beispielprogramm, welches als Argument ein oder mehrere Dateipfade erwartet und dann eine tar-Datei daraus erstellt, die auf stdout ausgegeben wird.