docs/cut

view cut.txt @ 12:9f17c512fb5c

Zwischenstand
author markus schnalke <meillo@marmaro.de>
date Mon, 11 May 2015 17:47:00 +0200
parents 04a8a33fc48a
children bf5e41260f89
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 4.3BSD-Reno + *BSDs
115 * This parser is less restrictive than the Draft 9 POSIX spec.
116 * POSIX doesn't allow lists that aren't in increasing order or
117 * overlapping lists. We also handle "-3-5" although there's no
118 * real reason too.
120 So gibt der Aufruf
121 von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8
122 in genau dieser Reihenfolge aus. Die Auswahl entspricht damit
123 der Mengenlehre in der Mathematik: Jedes angegebene Feld wird
124 Teil der Ergebnismenge. Die Felder der Ergebnismenge sind
125 dabei immer gleich geordnet wie in der Eingabe. Um die Worte
126 der Manpage XXX von Version 8 Unix wiederzugeben: ``In data base
127 parlance, it projects a relation.''
128 [ XXX
129 Cut fuehrt also die Datenbankoperation Projektion auf
130 Textdateien aus. Die Wikipedia erklaert das folgendermassen:
132 Die Projektion entspricht der Projektionsabbildung aus der
133 Mengenlehre und kann auch Attributbeschränkung genannt
134 werden. Sie extrahiert einzelne Attribute aus der
135 ursprünglichen Attributmenge und ist somit als eine Art
136 Selektion auf Spaltenebene zu verstehen, das heißt, die
137 Projektion blendet Spalten aus.
139 [ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
142 Geschichtliches
144 Cut erblickte 1982 mit dem Release von UNIX System III das
145 Licht der oeffentlichen Welt. Wenn man die Quellen von System
146 III durchforstet, findet man die Quellcodedatei cut.c mit dem
147 Zeitstempel 1980-04-11.
148 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
149 Das ist die aelteste Manifestation des Programms, die ich
150 aufstoebern konnte. Allerdings spricht die sccsid im
151 Quellcode von Version 1.5. Es muss also noch eine
152 Vorgeschichte geben. Zu dieser habe ich leider keinen Zugang
153 gefunden.
154 XXX mail an TUHS
156 Nun ein Blick auf die BSD-Linie: Dort ist mein
157 fruehester Fund ein cut.c mit dem Dateimodifikationsdatum
158 1986-11-07
159 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
160 als Teil der Spezialversion 4.3BSD-UWisc,
161 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
162 die im Januar 1987 veroeffentlicht wurde.
163 Die Implementierung unterscheidet sich nur minimal von der
164 in System III.
165 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut nicht auf.
166 Das darauf folgende 4.3BSD-Reno (1990) liefert aber wieder
167 ein cut mit aus. Dieses cut ist ein von Adam S. Moskowitz und
168 Marciano Pitargue neu implementiertes cut, das 1989 in BSD
169 aufgenommen wurde.
170 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
171 Seine Manpage
172 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
173 erwaehnt bereits die erwartete Konformitaet mit POSIX.2.
174 XXX 2 oder 3 modi?
175 Nun sollte man wissen, dass POSIX.2 erst im September
176 1992 veroeffentlicht wurde, also gut zwei Jahren nachdem die
177 Manpage und das Programm geschrieben wurden. Das Programm
178 wurde folglich anhand von Arbeitsversionen des Standards
179 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in
180 den Standardisierungsprozess geflossen; bis zur
181 Fertigstellung sollte es aber noch weitere zwei Jahre dauern.
183 Schaut man sich die SCCS-IDs (die vom damaligen
184 Versionskontrollsystem eingefuegt wurden) in den BSD-Quellen an,
185 dann findet man dort Versionsnummern, die die Entstehung
186 dokumentieren:
188 4.3BSD-UWisc "@(#)cut.c 1.3";
189 4.3BSD-Reno "@(#)cut.c 5.3 (Berkeley) 6/24/90";
190 NetBSD "@(#)cut.c 5.4 (Berkeley) 10/30/90";
191 FreeBSD "@(#)cut.c 8.1 (Berkeley) 6/6/93";
193 Die neueren BSD-Versionen enthalten zwar weiterhin eine SCCS-ID, diese
194 ist aber bei Version "8.3 (Berkeley) 5/4/95" stehen geblieben. Danach
195 wurde scheinbar von SCCS auf ein anderes
196 Versionskontrollsystem gewechselt.
197 XXX
199 Das cut der GNU Coreutils enthaelt folgenden Copyrightvermerk:
201 Copyright (C) 1997-2015 Free Software Foundation, Inc.
202 Copyright (C) 1984 David M. Ihnat
204 Der Code hat also ziemlich alte Urspruenge. Wie aus weiteren
205 Kommentaren zu entnehmen ist, wurde der Code zuerst von David
206 MacKenzie und spaeter von Jim Meyering ueberarbeitet. Letzterer
207 hat den Code 1992 auch ins Versionkontrollsystem eingestellt.
208 Weshalb die Jahre zwischen 1992 und 1997 nicht im Copyright-Vermerk
209 auftauchen, ist unklar.
211 Trotz der vielen Jahreszahlen aus den 80er Jahren gehoert cut,
212 aus Sicht des urspruenglichen Unix, zu den juengeren Tools.
213 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist,
214 so war Unix doch schon ueber zehn Jahre alt, als cut das
215 erste Mal auftauchte. Insbesondere gehoerte cut auch noch nicht
216 zu Version 7 Unix, das die Ausgangsbasis aller modernen
217 Unix-Systeme darstellt. Die weit komplexeren Programme sed
218 und awk waren dort schon vertreten. Man muss sich also
219 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es
220 schon zwei Programme gab, die die Funktion von cut abdecken
221 konnten. Ein Argument fuer cut war sicher seine Kompaktheit und
222 die damit verbundene Geschwindigkeit gegenueber dem damals
223 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix
224 Philosopie entspricht: Mache eine Aufgabe und die richtig!
225 Cut ueberzeugte. Es wurde in andere Unix Varianten uebernommen,
226 standardisiert und ist heutzutage ueberall anzutreffen.
228 Die urspruengliche Variante (ohne -b) wurde schon 1985 in
229 der System V Interface Definition, einer wichtigen formalen
230 Beschreibung von UNIX System V, spezifiziert und tauchte
231 anschliessend in allen relevanten Standards auf. Mit POSIX.2
232 im Jahre 1992 wurde cut zum ersten Mal in der heutigen Form
233 (mit -b) standardisiert.
234 XXX sicher? s.o.
237 Multibyte-Unterstuetzung
239 Nun sind der Bytemodus und die damit verbundene
240 Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit
241 1992 standardisiert, wie steht es aber mit deren Umsetzung?
242 Welche Versionen implementieren POSIX korrekt?
243 Die Situation ist dreiteilig: Es gibt traditionelle
244 Implementierungen, die nur -c und -f kennen. Dann gibt es
245 Implementierungen die -b zwar kennen, es aber lediglich als Alias
246 fuer -c handhaben. Diese Implementierungen funktionieren mit
247 Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei
248 Multi-Byte-Encodings (z.B. UTF-8) verhaelt sich ihr -c aber
249 wie -b (und -n wird ignoriert). Schliesslich gibt es noch
250 Implementierungen, die -b und -c tatsaechlich POSIX-konform
251 implementieren.
253 Traditionelle Zwei-Modi-Implementierungen sind z.B. die von
254 System III, System V und die aller BSDs bis in die 90er.
256 Pseudo-Multibyte-Implementierungen bieten GNU und die
257 modernen NetBSDs und OpenBSDs. Wie sehr dort ein Schein von
258 POSIX-Konformitaet gewahrt wird, ist unterschiedlich. Nicht
259 immer findet man klare Aussagen wie diese:
261 /* Since we don't support multi-byte characters, the -c and -b
262 options are equivalent, and the -n option is meaningless. */
264 [ XXX
266 Tatsaechlich standardkonforme Implementierungen, die
267 Multibytes korrekt handhaben, bekommt man bei einem modernen
268 FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins
269 im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert.
270 [ https://svnweb.freebsd.org/base?view=revision&revision=131194
271 Warum die beiden anderen grossen BSDs diese Aenderung nicht
272 uebernommen haben, bleibt offen. Es scheint aber an der im
273 obigen Kommentar formulierten Grundausrichtung zu liegen.
275 Wie findet man als Nutzer heraus, ob beim cut(1) des eigenen
276 Systems Multibytes korrekt unterstuetzt werden? Zuerst ist
277 entscheidend, ob das System selbst mit einem Multibyte-Encoding
278 arbeitet, denn tut es das nicht, dann entsprechen sich naemlich
279 Zeichen und Bytes und die Frage eruebrigt sich. Man kann das
280 herausfinden indem man sich das Locale anschaut, aber einfacher
281 ist es, ein typisches Mehrbytezeichen, wie z.B. einen Umlaut,
282 auszugeben und zu schauen ob dieses in einem oder in mehreren
283 Bytes kodiert ist:
285 $ echo ä | od -c
286 0000000 303 244 \n
287 0000003
289 In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den
290 Zeilenumbruch fuegt echo(1) hinzu.)
292 Mit dem Programm iconv(1) kann man Text explizit in bestimmte
293 Kodierungen konvertieren. Hier Beispiele, wie die Ausgabe
294 bei Latin1 und wie sie bei UTF-8 aussieht.
296 $ echo ä | iconv -t latin1 | od -c
297 0000000 344 \n
298 0000002
300 $ echo ä | iconv -t utf8 | od -c
301 0000000 303 244 \n
302 0000003
304 Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung)
305 wird recht sicher einer dieser beiden Ausgaben entsprechen.
307 Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System,
308 dann sollte sich eine POSIX-konforme Implementierung so verhalten:
310 $ echo ä | ./cut -c 1 | od -c
311 0000000 303 244 \n
312 0000003
314 $ echo ä | ./cut -b 1 | od -c
315 0000000 303 \n
316 0000002
318 $ echo ä | ./cut -b 1 -n | od -c
319 0000000 \n
320 0000001
322 Bei einer Pseudo-POSIX-Implementierung ist die Ausgabe in
323 allen drei Faellen wie die mittlere: Es wird das erste Byte
324 ausgegeben.
327 Implementierungen
329 Nun ein Blick auf den Code. Betrachtet wird eine Auswahl an
330 Implementierungen.
332 Fuer einen ersten Eindruck ist der Umfang des Quellcodes
333 hilfreich. Typischerweise steigt dieser ueber die Jahre an. Diese
334 Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall,
335 bestaetigt werden. Die Unterstuetzung des Byte-Modus (-b)
336 erfordert zwangslaeufig mehr Code, deshalb sind die
337 POSIX-konformen Implementierungen tendenziell umfangreicher.
340 SLOC Zeilen Bytes Gehoert zu Dateidatum Kategorie
341 -----------------------------------------------------------------
342 116 123 2966 System III 1980-04-11 (trad)
343 118 125 3038 4.3BSD-UWisc 1986-11-07 (trad)
344 200 256 5715 4.3BSD-Reno 1990-06-25 (trad)
345 200 270 6545 NetBSD 1993-03-21 (trad)
346 218 290 6892 OpenBSD 2008-06-27 (pseudo)
347 224 296 6920 FreeBSD 1994-05-27 (trad)
348 232 306 7500 NetBSD 2014-02-03 (pseudo)
349 340 405 7423 Heirloom 2012-05-20 (POSIX)
350 382 586 14175 GNU coreutils 1992-11-08 (pseudo)
351 391 479 10961 FreeBSD 2012-11-24 (POSIX)
352 588 830 23167 GNU coreutils 2015-05-01 (pseudo)
353 XXX verlinken
356 Das Kandidatenfeld teilt sich grob in vier Gruppen: (1) Die zwei
357 urspruenglichen Implementierungen, die sich nur minimal
358 unterscheiden, mit gut 100 SLOCs. (2) Die fuenf BSD-Versionen mit
359 gut 200 SLOCs. (3) Die zwei POSIX-konformen Programme und
360 die alte GNU-Version mit 340-390 SLOCs. Und (4) die moderne
361 GNU-Variante mit fast 600 SLOCs.
363 Die Abweichung zwischen logischen Codezeilen (SLOC, ermittelt mit
364 SLOCcount) und der Anzahl von Zeilenumbruechen in der Datei (`wc
365 -l') erstreckt sich ueber einen Faktor von 1.06 bei den aeltesten
366 Vertretern bis zu Faktor 1.5 bei GNU. Der groesste
367 Einflussfaktor darauf sind Leerzeilen, reine Kommentarzeilen und
368 die Groesse des Lizenzblocks am Dateianfang.
370 Betrachtet man die Abweichungen zwischen den logischen Codezeilen
371 und der Dateigroesse (`wc -c'), so pendelt das Teilnehmerfeld
372 zwischen 25 und 30 Bytes je Anweisung. Die Heirloom-Implementierung
373 weicht mit nur 21 nach unten ab, die GNU-Implementierungen mit
374 fast 40 nach oben. Dies liegt bei GNU hauptsaechlich an deren
375 Programmierstil, mit spezieller Einrueckung und langen Bezeichnern.
376 Ob man die Heirloom-Implementierung als besonders kryptisch
377 oder als besonders elegant bezeichnen will, das soll der
378 eigenen Einschaetzung des Lesers ueberlassen bleiben.
381 Die interne Struktur des C-Codes ist meist aehnlich. Neben der
382 obligatorischen main-Funktion, die die Kommandozeilenargumente
383 verarbeitet, gibt es im Normalfall eine Funktion, die die
384 Feldauswahl in eine interne Datenstruktur ueberfuehrt, desweiteren
385 haben fast alle Implementierungen separate Funktionen fuer die
386 zwei bzw. drei Modi. Bei den POSIX-konformen Implementierungen
387 wird die `-b -n'-Kombination als weiterer Modus behandelt, und
388 damit in einer eigenen Funktion umgesetzt. Nur bei der fruehen
389 System III-Implementierung (und seiner 4.3BSD-UWisc-Variante)
390 wird nichts aus der main-Funktion ausgelagert, ausser den
391 Fehlerausgaben.
393 Bei System III ist die Anzahl der moeglichen Felder und ebenso
394 die Zeilenlaenge auf 512 begrenzt. 4.3BSD-Reno und die BSDs
395 der 90er Jahre haben ebenfalls fixe Grenzen (_BSD_LINE_MAX
396 bzw. _POSIX2_LINE_MAX). Bei modernen FreeBSDs, NetBSDs, bei
397 allen GNU-Implementierungen und bei Heirloom kann sowohl
398 die Felderanzahl als auch die maximale Zeilenlaenge beliebig
399 gross werden; der Speicher dafür wird dynamisch alloziiert.
400 OpenBSD ist ein Hybrid aus fixer Maximalzahl an Feldern, aber
401 beliebiger Zeilenlaenge (fgetln). XXX
405 Beschreibungen
407 Interessant ist auch ein Vergleich der Kurzbeschreibungen von
408 cut, wie sie sich in der Titelzeile von Manpages oder manchmal
409 auch am Anfang der Quellcodedatei finden. Die folgende Liste
410 ist grob zeitlich geordnet und nach Abstammung gruppiert:
413 System III cut out selected fields of each line of a file
414 System III (src) cut and paste columns of a table (projection of a relation)
415 System V cut out selected fields of each line of a file
416 HP-UX cut out (extract) selected fields of each line of a file
418 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
419 4.3BSD-Reno select portions of each line of a file
420 NetBSD select portions of each line of a file
421 OpenBSD 4.6 select portions of each line of a file
422 FreeBSD 1.0 select portions of each line of a file
423 FreeBSD 10.0 cut out selected portions of each line of a file
424 SunOS 4.1.3 remove selected fields from each line of a file
425 SunOS 5.5.1 cut out selected fields of each line of a file
427 Heirloom Tools cut out selected fields of each line of a file
428 Heirloom Tools (src) cut out fields of lines of files
430 GNU coreutils remove sections from each line of files
432 Minix select out columns of a file
434 Version 8 Unix rearrange columns of data
435 ``Unix Reader'' rearrange columns of text
437 POSIX cut out selected fields of each line of a file
440 Die mit ``(src)'' markierten Beschreibungen sind aus dem
441 jeweiligen Quellcode entnommen.
442 Der POSIX-Eintrag enthaelt die Beschreibung des Standards.
443 Der ``Unix Reader'' ist ein rueckblickendes Textdokument von
444 Doug McIlroy, das das Auftreten von Tools in der Geschichte
445 des Research Unix zum Thema hat.
446 [ XXX
447 Eigentlich sollte seine
448 Beschreibung der in Version 8 Unix entsprechen. Die
449 Abweichung koennte sowohl ein Uebertragungsfehler als auch
450 eine nachtraegliche Korrektur sein.
451 Alle uebrigen Beschreibungen entstammen den Manpages.
453 Oft ist mit der Zeit die POSIX-Beschreibung uebernommen
454 worden, wie beispielsweise bei FreeBSD zu sehen.
455 [ https://svnweb.freebsd.org/base?view=revision&revision=167101
456 XXX fixme!
458 Interessant ist, dass die GNU coreutils seit Anbeginn vom
459 Entfernen von Teilen der Eingabe sprechen, wohingegen die
460 Kommandozeilenangabe klar ein Auswaehlen darstellt. Die
461 Worte ``cut out'' sind vielleicht auch nur etwas zu
462 missverstaendlich. HP-UX hat sie deshalb praezisiert.
464 Auch beim Begriff, was selektiert wird, ist man sich
465 uneins. Die einen reden von Feldern (POSIX), andere von
466 Abschnitten bzw. Teilen (BSD) und wieder andere von Spalten
467 (Research Unix). Ironischerweise leistet sich gerade Version
468 8 Unix, das eigentlich um eine sehr treffende Weltsicht
469 bemueht ist, mit ``rearrange columns of data'' die
470 unzutreffendste der Beschreibungen.
473 Autoreninfo
475 Markus Schnalke interessiert sich fuer die Hintergruende
476 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses
477 Textes wurde er regelrecht zum Historiker.
480 Lizenz
482 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported
483 veroeffentlicht werden)