docs/cut

view cut.txt @ 14:21ad1c1548c4

Code ausgewaehlter Implementierungen eingefuegt Das Datum entspricht dem Dateiaenderungsdatum.
author markus schnalke <meillo@marmaro.de>
date Tue, 12 May 2015 06:46:59 +0200
parents 9f17c512fb5c
children 77d1f55bba08
line source
1 Das Werkzeugkaestle, #1
3 cut - cut out selected fields of each line of a file
4 ----------------------------------------------------
5 markus schnalke <meillo@marmaro.de>
6 2015-05
9 Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
10 In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt
11 es, denn es ist ein schoenes, praktisches und anschauliches
12 Helferlein. Hier soll ein wenig hinter seine Fassade geschaut
13 werden.
16 Funktionsweise
18 Urspruenglich hatte cut zwei Modi, die spaeter um einen dritten
19 erweitert wurden. Cut schneidet entweder gewuenschte Zeichen aus
20 den Zeilen der Eingabe oder gewuenschte, durch Trennzeichen
21 definierte, Felder.
23 Der Zeichenmodus ist optimal geeignet um Festbreitenformate zu
24 zerteilen. So kann man damit beispielsweise bestimmte
25 Zugriffsrechte aus der Ausgabe von `ls -l' ausschneiden, in
26 diesem Beispiel die Rechte des Besitzers:
28 $ ls -l foo | cut -c 2-4
29 rw-
31 Oder die Schreibrechte des Besitzers, der Gruppe und der
32 Welt:
34 $ ls -l | cut -c 3,6,9
35 ww-
37 Mit cut lassen sich aber auch Strings kuerzen.
39 $ long=12345678901234567890
40 $ echo "$long" | cut -c -10
41 1234567890
43 Dieser Befehl gibt die ersten maximal 10 Zeichen von
44 `$long' aus. (Alternativ kann man hierfuer auch `printf
45 "%.10s\n" "$long"' verwenden.)
47 Geht es aber nicht um die Darstellung von Zeichen, sondern um
48 ihre Speicherung, dann ist `-c' nicht unbedingt geeignet.
49 Frueher, als US-ASCII als Zeichensatz und -kodierung
50 noch omnipraesent war, wurde jedes Zeichen mit genau einem
51 Byte gespeichert. Somit selektierte `cut -c' gleichermassen
52 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
53 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
54 dieser Annahme loesen. In diesem Zug bekam cut mit
55 POSIX.2-1992 einen Bytemodus (Option `-b'). Will man
56 also nur die ersten maximal 500 Bytes vor dem
57 Newline-Zeichen stehen haben (und den Rest stillschweigend
58 ignorieren), dann macht man das mit:
60 $ cut -b -500
62 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese
63 Funktion ist insbesondere fuer POSIX wichtig, da man so
64 Textdateien mit begrenzter Zeilenlaenge erzeugen kann.
65 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17
67 Auch wenn der Bytemodus neu eingefuehrt wurde, so sollte er
68 sich doch nur so verhalten wie der alte Zeichenmodus normalerweise
69 implementiert war. Beim Zeichenmodus aber wurde durch POSIX.2
70 eine andere Implementierungsweise gefordert. Das Problem war
71 also nicht, den neuen Bytemodus zu implementieren, sondern
72 den Zeichenmodus neu zu implementieren.
74 Neben dem Zeichen- und Byte-Modus bietet cut noch den
75 Feld-Modus, den man mit `-f' einleitet. Mit ihm
76 koennen Felder ausgewaehlt werden. Das Trennzeichen (per
77 Default der Tab) kann mit `-d' geaendert werden.
79 Der typische Anwendungsfall fuer cut im Feld-Modus ist die
80 Auswahl von Information aus der passwd-Datei. So z.B. der
81 Benutzername, seine ID und das Homeverzeichnis:
83 $ cut -d: -f1,3,6 /etc/passwd
84 root:0:/root
85 bin:1:/bin
86 daemon:2:/sbin
87 mail:8:/var/spool/mail
88 ...
90 (Die Argumente fuer die Optionen koennen bei cut uebrigens
91 mit Whitespace abgetrennt oder direkt angehaengt folgen.)
93 Dieser Feld-Modus ist fuer einfache tabellarische Dateien,
94 wie eben die passwd, gut geeignet. Er kommt aber schnell an
95 seine Grenzen. Gerade der haeufige Fall, dass an Whitespace
96 in Felder geteilt werden soll, wird damit nicht abgedeckt.
97 Der Delimiter kann nur genau ein Zeichen sein. Es kann also
98 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden.
99 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander
100 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses
101 Verhalten widerspricht den Erwartungen, die man an die
102 Verarbeitung einer Datei mit Whitespace-getrennten Feldern
103 hat. Manche Implementierungen von cut, z.B. die von FreeBSD,
104 haben aber Erweiterungen, die das gewuenschte Verhalten fuer
105 Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn
106 man portabel bleiben will, verwendet man awk in diesen
107 Faellen.
109 Awk bietet noch eine weitere Funktion, die cut missen
110 laesst: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei
111 cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein
112 Feld kann selbst mehrfach angegeben werden.
114 XXX
115 4.3BSD-Reno + *BSDs
116 * This parser is less restrictive than the Draft 9 POSIX spec.
117 * POSIX doesn't allow lists that aren't in increasing order or
118 * overlapping lists. We also handle "-3-5" although there's no
119 * real reason too.
121 So gibt der Aufruf
122 von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8
123 in genau dieser Reihenfolge aus. Die Auswahl entspricht damit
124 der Mengenlehre in der Mathematik: Jedes angegebene Feld wird
125 Teil der Ergebnismenge. Die Felder der Ergebnismenge sind
126 dabei immer gleich geordnet wie in der Eingabe. Um die Worte
127 der Manpage XXX von Version 8 Unix wiederzugeben: ``In data base
128 parlance, it projects a relation.''
129 [ XXX
130 Cut fuehrt also die Datenbankoperation Projektion auf
131 Textdateien aus. Die Wikipedia erklaert das folgendermassen:
133 Die Projektion entspricht der Projektionsabbildung aus der
134 Mengenlehre und kann auch Attributbeschränkung genannt
135 werden. Sie extrahiert einzelne Attribute aus der
136 ursprünglichen Attributmenge und ist somit als eine Art
137 Selektion auf Spaltenebene zu verstehen, das heißt, die
138 Projektion blendet Spalten aus.
140 [ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
143 Geschichtliches
145 Cut erblickte 1982 mit dem Release von UNIX System III das
146 Licht der oeffentlichen Welt. Wenn man die Quellen von System
147 III durchforstet, findet man die Quellcodedatei cut.c mit dem
148 Zeitstempel 1980-04-11.
149 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
150 Das ist die aelteste Manifestation des Programms, die ich
151 aufstoebern konnte. Allerdings spricht die sccsid im
152 Quellcode von Version 1.5. Es muss also noch eine
153 Vorgeschichte geben. Zu dieser habe ich leider keinen Zugang
154 gefunden.
155 XXX mail an TUHS
157 Nun ein Blick auf die BSD-Linie: Dort ist mein
158 fruehester Fund ein cut.c mit dem Dateimodifikationsdatum
159 1986-11-07
160 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
161 als Teil der Spezialversion 4.3BSD-UWisc,
162 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
163 die im Januar 1987 veroeffentlicht wurde.
164 Die Implementierung unterscheidet sich nur minimal von der
165 in System III.
166 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut nicht auf.
167 Das darauf folgende 4.3BSD-Reno (1990) liefert aber wieder
168 ein cut mit aus. Dieses cut ist ein von Adam S. Moskowitz und
169 Marciano Pitargue neu implementiertes cut, das 1989 in BSD
170 aufgenommen wurde.
171 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
172 Seine Manpage
173 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
174 erwaehnt bereits die erwartete Konformitaet mit POSIX.2.
175 XXX 2 oder 3 modi?
176 Nun sollte man wissen, dass POSIX.2 erst im September
177 1992 veroeffentlicht wurde, also gut zwei Jahren nachdem die
178 Manpage und das Programm geschrieben wurden. Das Programm
179 wurde folglich anhand von Arbeitsversionen des Standards
180 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in
181 den Standardisierungsprozess geflossen; bis zur
182 Fertigstellung sollte es aber noch weitere zwei Jahre dauern.
184 XXX
185 Schaut man sich die SCCS-IDs (die vom damaligen
186 Versionskontrollsystem eingefuegt wurden) in den BSD-Quellen an,
187 dann findet man dort Versionsnummern, die die Entstehung
188 dokumentieren:
190 4.3BSD-UWisc "@(#)cut.c 1.3";
191 4.3BSD-Reno "@(#)cut.c 5.3 (Berkeley) 6/24/90";
192 NetBSD "@(#)cut.c 5.4 (Berkeley) 10/30/90";
193 FreeBSD "@(#)cut.c 8.1 (Berkeley) 6/6/93";
195 Die neueren BSD-Versionen enthalten zwar weiterhin eine SCCS-ID, diese
196 ist aber bei Version "8.3 (Berkeley) 5/4/95" stehen geblieben. Danach
197 wurde scheinbar von SCCS auf ein anderes
198 Versionskontrollsystem gewechselt.
199 XXX
201 Das cut der GNU Coreutils enthaelt folgenden Copyrightvermerk:
203 Copyright (C) 1997-2015 Free Software Foundation, Inc.
204 Copyright (C) 1984 David M. Ihnat
206 Der Code hat also ziemlich alte Urspruenge. Wie aus weiteren
207 Kommentaren zu entnehmen ist, wurde der Code zuerst von David
208 MacKenzie und spaeter von Jim Meyering ueberarbeitet. Letzterer
209 hat den Code 1992 auch ins Versionkontrollsystem eingestellt.
210 Weshalb die Jahre zwischen 1992 und 1997 nicht im Copyright-Vermerk
211 auftauchen, ist unklar.
213 Trotz der vielen Jahreszahlen aus den 80er Jahren gehoert cut,
214 aus Sicht des urspruenglichen Unix, zu den juengeren Tools.
215 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist,
216 so war Unix doch schon ueber zehn Jahre alt, als cut das
217 erste Mal auftauchte. Insbesondere gehoerte cut auch noch nicht
218 zu Version 7 Unix, das die Ausgangsbasis aller modernen
219 Unix-Systeme darstellt. Die weit komplexeren Programme sed
220 und awk waren dort schon vertreten. Man muss sich also
221 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es
222 schon zwei Programme gab, die die Funktion von cut abdecken
223 konnten. Ein Argument fuer cut war sicher seine Kompaktheit und
224 die damit verbundene Geschwindigkeit gegenueber dem damals
225 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix
226 Philosopie entspricht: Mache eine Aufgabe und die richtig!
227 Cut ueberzeugte. Es wurde in andere Unix Varianten uebernommen,
228 standardisiert und ist heutzutage ueberall anzutreffen.
230 Die urspruengliche Variante (ohne -b) wurde schon 1985 in
231 der System V Interface Definition, einer wichtigen formalen
232 Beschreibung von UNIX System V, spezifiziert und tauchte
233 anschliessend in allen relevanten Standards auf. Mit POSIX.2
234 im Jahre 1992 wurde cut zum ersten Mal in der heutigen Form
235 (mit -b) standardisiert.
236 XXX sicher? s.o.
239 Multibyte-Unterstuetzung
241 Nun sind der Bytemodus und die damit verbundene
242 Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit
243 1992 standardisiert, wie steht es aber mit deren Umsetzung?
244 Welche Versionen implementieren POSIX korrekt?
245 Die Situation ist dreiteilig: Es gibt traditionelle
246 Implementierungen, die nur -c und -f kennen. Dann gibt es
247 Implementierungen die -b zwar kennen, es aber lediglich als Alias
248 fuer -c handhaben. Diese Implementierungen funktionieren mit
249 Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei
250 Multi-Byte-Encodings (z.B. UTF-8) verhaelt sich ihr -c aber
251 wie -b (und -n wird ignoriert). Schliesslich gibt es noch
252 Implementierungen, die -b und -c tatsaechlich POSIX-konform
253 implementieren.
255 Traditionelle Zwei-Modi-Implementierungen sind z.B. die von
256 System III, System V und die aller BSDs bis in die 90er.
258 Pseudo-Multibyte-Implementierungen bieten GNU und die
259 modernen NetBSDs und OpenBSDs. Wie sehr dort ein Schein von
260 POSIX-Konformitaet gewahrt wird, ist unterschiedlich. Nicht
261 immer findet man klare Aussagen wie diese:
263 /* Since we don't support multi-byte characters, the -c and -b
264 options are equivalent, and the -n option is meaningless. */
266 [ XXX
268 Tatsaechlich standardkonforme Implementierungen, die
269 Multibytes korrekt handhaben, bekommt man bei einem modernen
270 FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins
271 im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert.
272 [ https://svnweb.freebsd.org/base?view=revision&revision=131194
273 Warum die beiden anderen grossen BSDs diese Aenderung nicht
274 uebernommen haben, bleibt offen. Es scheint aber an der im
275 obigen Kommentar formulierten Grundausrichtung zu liegen.
277 Wie findet man als Nutzer heraus, ob beim cut(1) des eigenen
278 Systems Multibytes korrekt unterstuetzt werden? Zuerst ist
279 entscheidend, ob das System selbst mit einem Multibyte-Encoding
280 arbeitet, denn tut es das nicht, dann entsprechen sich naemlich
281 Zeichen und Bytes und die Frage eruebrigt sich. Man kann das
282 herausfinden indem man sich das Locale anschaut, aber einfacher
283 ist es, ein typisches Mehrbytezeichen, wie z.B. einen Umlaut,
284 auszugeben und zu schauen ob dieses in einem oder in mehreren
285 Bytes kodiert ist:
287 $ echo ä | od -c
288 0000000 303 244 \n
289 0000003
291 In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den
292 Zeilenumbruch fuegt echo(1) hinzu.)
294 Mit dem Programm iconv(1) kann man Text explizit in bestimmte
295 Kodierungen konvertieren. Hier Beispiele, wie die Ausgabe
296 bei Latin1 und wie sie bei UTF-8 aussieht.
298 $ echo ä | iconv -t latin1 | od -c
299 0000000 344 \n
300 0000002
302 $ echo ä | iconv -t utf8 | od -c
303 0000000 303 244 \n
304 0000003
306 Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung)
307 wird recht sicher einer dieser beiden Ausgaben entsprechen.
309 Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System,
310 dann sollte sich eine POSIX-konforme Implementierung so verhalten:
312 $ echo ä | ./cut -c 1 | od -c
313 0000000 303 244 \n
314 0000003
316 $ echo ä | ./cut -b 1 | od -c
317 0000000 303 \n
318 0000002
320 $ echo ä | ./cut -b 1 -n | od -c
321 0000000 \n
322 0000001
324 Bei einer Pseudo-POSIX-Implementierung ist die Ausgabe in
325 allen drei Faellen wie die mittlere: Es wird das erste Byte
326 ausgegeben.
329 Implementierungen
331 Nun ein Blick auf den Code. Betrachtet wird eine Auswahl an
332 Implementierungen.
334 Fuer einen ersten Eindruck ist der Umfang des Quellcodes
335 hilfreich. Typischerweise steigt dieser ueber die Jahre an. Diese
336 Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall,
337 bestaetigt werden. Die Unterstuetzung des Byte-Modus (-b)
338 erfordert zwangslaeufig mehr Code, deshalb sind die
339 POSIX-konformen Implementierungen tendenziell umfangreicher.
342 SLOC Zeilen Bytes Gehoert zu Dateidatum Kategorie
343 -----------------------------------------------------------------
344 116 123 2966 System III 1980-04-11 (trad)
345 118 125 3038 4.3BSD-UWisc 1986-11-07 (trad)
346 200 256 5715 4.3BSD-Reno 1990-06-25 (trad)
347 200 270 6545 NetBSD 1993-03-21 (trad)
348 218 290 6892 OpenBSD 2008-06-27 (pseudo)
349 224 296 6920 FreeBSD 1994-05-27 (trad)
350 232 306 7500 NetBSD 2014-02-03 (pseudo)
351 340 405 7423 Heirloom 2012-05-20 (POSIX)
352 382 586 14175 GNU coreutils 1992-11-08 (pseudo)
353 391 479 10961 FreeBSD 2012-11-24 (POSIX)
354 588 830 23167 GNU coreutils 2015-05-01 (pseudo)
355 XXX verlinken
358 Das Kandidatenfeld teilt sich grob in vier Gruppen: (1) Die zwei
359 urspruenglichen Implementierungen, die sich nur minimal
360 unterscheiden, mit gut 100 SLOCs. (2) Die fuenf BSD-Versionen mit
361 gut 200 SLOCs. (3) Die zwei POSIX-konformen Programme und
362 die alte GNU-Version mit 340-390 SLOCs. Und (4) die moderne
363 GNU-Variante mit fast 600 SLOCs.
365 Die Abweichung zwischen logischen Codezeilen (SLOC, ermittelt mit
366 SLOCcount) und der Anzahl von Zeilenumbruechen in der Datei (`wc
367 -l') erstreckt sich ueber einen Faktor von 1.06 bei den aeltesten
368 Vertretern bis zu Faktor 1.5 bei GNU. Der groesste
369 Einflussfaktor darauf sind Leerzeilen, reine Kommentarzeilen und
370 die Groesse des Lizenzblocks am Dateianfang.
372 Betrachtet man die Abweichungen zwischen den logischen Codezeilen
373 und der Dateigroesse (`wc -c'), so pendelt das Teilnehmerfeld
374 zwischen 25 und 30 Bytes je Anweisung. Die Heirloom-Implementierung
375 weicht mit nur 21 nach unten ab, die GNU-Implementierungen mit
376 fast 40 nach oben. Dies liegt bei GNU hauptsaechlich an deren
377 Programmierstil, mit spezieller Einrueckung und langen Bezeichnern.
378 Ob man die Heirloom-Implementierung als besonders kryptisch
379 oder als besonders elegant bezeichnen will, das soll der
380 eigenen Einschaetzung des Lesers ueberlassen bleiben.
383 Die interne Struktur des C-Codes ist meist aehnlich. Neben der
384 obligatorischen main-Funktion, die die Kommandozeilenargumente
385 verarbeitet, gibt es im Normalfall eine Funktion, die die
386 Feldauswahl in eine interne Datenstruktur ueberfuehrt. Desweiteren
387 haben fast alle Implementierungen separate Funktionen fuer die
388 zwei bzw. drei Modi. Bei den POSIX-konformen Implementierungen
389 wird die `-b -n'-Kombination als weiterer Modus behandelt, und
390 damit in einer eigenen Funktion umgesetzt. Nur bei der fruehen
391 System III-Implementierung (und seiner 4.3BSD-UWisc-Variante)
392 wird ausser den Fehlerausgaben nichts aus der main-Funktion
393 ausgelagert.
395 XXX
396 Bei System III ist die Anzahl der moeglichen Felder und ebenso
397 die Zeilenlaenge auf 512 begrenzt. 4.3BSD-Reno und die BSDs
398 der 90er Jahre haben ebenfalls fixe Grenzen (_BSD_LINE_MAX
399 bzw. _POSIX2_LINE_MAX). Bei modernen FreeBSDs, NetBSDs, bei
400 allen GNU-Implementierungen und bei Heirloom kann sowohl
401 die Felderanzahl als auch die maximale Zeilenlaenge beliebig
402 gross werden; der Speicher dafür wird dynamisch alloziiert.
403 OpenBSD ist ein Hybrid aus fixer Maximalzahl an Feldern, aber
404 beliebiger Zeilenlaenge (fgetln). XXX
407 Beschreibungen
409 Interessant ist auch ein Vergleich der Kurzbeschreibungen von
410 cut, wie sie sich in der Titelzeile von Manpages oder manchmal
411 auch am Anfang der Quellcodedatei finden. Die folgende Liste
412 ist grob zeitlich geordnet und nach Abstammung gruppiert:
415 System III cut out selected fields of each line of a file
416 System III (src) cut and paste columns of a table (projection of a relation)
417 System V cut out selected fields of each line of a file
418 HP-UX cut out (extract) selected fields of each line of a file
420 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
421 4.3BSD-Reno select portions of each line of a file
422 NetBSD select portions of each line of a file
423 OpenBSD 4.6 select portions of each line of a file
424 FreeBSD 1.0 select portions of each line of a file
425 FreeBSD 10.0 cut out selected portions of each line of a file
426 SunOS 4.1.3 remove selected fields from each line of a file
427 SunOS 5.5.1 cut out selected fields of each line of a file
429 Heirloom Tools cut out selected fields of each line of a file
430 Heirloom Tools (src) cut out fields of lines of files
432 GNU coreutils remove sections from each line of files
434 Minix select out columns of a file
436 Version 8 Unix rearrange columns of data
437 ``Unix Reader'' rearrange columns of text
439 POSIX cut out selected fields of each line of a file
442 Die mit ``(src)'' markierten Beschreibungen sind aus dem
443 jeweiligen Quellcode entnommen.
444 Der POSIX-Eintrag enthaelt die Beschreibung des Standards.
445 Der ``Unix Reader'' ist ein rueckblickendes Textdokument von
446 Doug McIlroy, das das Auftreten von Tools in der Geschichte
447 des Research Unix zum Thema hat.
448 [ XXX
449 Eigentlich sollte seine
450 Beschreibung der in Version 8 Unix entsprechen. Die
451 Abweichung koennte sowohl ein Uebertragungsfehler als auch
452 eine nachtraegliche Korrektur sein.
453 Alle uebrigen Beschreibungen entstammen den Manpages.
455 Oft ist mit der Zeit die POSIX-Beschreibung uebernommen
456 worden, wie beispielsweise bei FreeBSD zu sehen.
457 [ https://svnweb.freebsd.org/base?view=revision&revision=167101
458 XXX fixme!
460 Interessant ist, dass die GNU coreutils seit Anbeginn vom
461 Entfernen von Teilen der Eingabe sprechen, wohingegen die
462 Kommandozeilenangabe klar ein Auswaehlen darstellt. Die
463 Worte ``cut out'' sind vielleicht auch nur etwas zu
464 missverstaendlich. HP-UX hat sie deshalb praezisiert.
466 Auch beim Begriff, was selektiert wird, ist man sich
467 uneins. Die einen reden von Feldern (POSIX), andere von
468 Abschnitten bzw. Teilen (BSD) und wieder andere von Spalten
469 (Research Unix). Ironischerweise leistet sich gerade Version
470 8 Unix, das eigentlich um eine sehr treffende Weltsicht
471 bemueht ist, mit ``rearrange columns of data'' die
472 unzutreffendste der Beschreibungen.
475 Autoreninfo
477 Markus Schnalke interessiert sich fuer die Hintergruende
478 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses
479 Textes wurde er regelrecht zum Historiker.
482 Lizenz
484 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported
485 veroeffentlicht werden)