docs/cut

diff cut.de.ms @ 26:3b4e53e04958

Mit troff gesetzte Version hinzugefuegt
author markus schnalke <meillo@marmaro.de>
date Sun, 12 Jul 2015 09:51:48 +0200
parents
children c584c7d907c5
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/cut.de.ms	Sun Jul 12 09:51:48 2015 +0200
     1.3 @@ -0,0 +1,517 @@
     1.4 +.so macros
     1.5 +.lc_ctype de_DE.utf8
     1.6 +
     1.7 +.TL
     1.8 +Cut out selected fields of each line of a file
     1.9 +.AU
    1.10 +markus schnalke <meillo@marmaro.de>
    1.11 +..
    1.12 +.FS
    1.13 +2015-05.
    1.14 +Dieser Text steht unter CC0.
    1.15 +Er ist online verfügbar:
    1.16 +.I http://marmaro.de/docs/
    1.17 +.FE
    1.18 +
    1.19 +.LP
    1.20 +Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
    1.21 +In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt
    1.22 +es, denn es ist ein schönes, praktisches und anschauliches
    1.23 +Helferlein. Hier soll ein wenig hinter seine Fassade geschaut
    1.24 +werden.
    1.25 +.SH
    1.26 +Funktionsweise
    1.27 +.LP
    1.28 +Ursprünglich hatte cut zwei Modi, die später um einen dritten
    1.29 +erweitert wurden. Cut schneidet entweder gewünschte Zeichen aus
    1.30 +den Zeilen der Eingabe oder gewünschte, durch Trennzeichen
    1.31 +definierte, Felder.
    1.32 +.PP
    1.33 +Der Zeichenmodus ist optimal geeignet um Festbreitenformate zu
    1.34 +zerteilen. Man kann damit beispielsweise bestimmte
    1.35 +Zugriffsrechte aus der Ausgabe von \f(CWls -l\fP ausschneiden, in
    1.36 +diesem Beispiel die Rechte des Besitzers:
    1.37 +.CS
    1.38 +	$ ls -l foo
    1.39 +	-rw-rw-r-- 1 meillo users 0 May 12 07:32 foo
    1.40 +.sp .3
    1.41 +	$ ls -l foo | cut -c 2-4
    1.42 +	rw-
    1.43 +.CE
    1.44 +.LP
    1.45 +Oder die Schreibrechte des Besitzers, der Gruppe und der
    1.46 +Welt:
    1.47 +.CS
    1.48 +	$ ls -l foo | cut -c 3,6,9
    1.49 +	ww-
    1.50 +.CE
    1.51 +.LP
    1.52 +Mit cut lassen sich aber auch Strings kürzen.
    1.53 +.CS
    1.54 +	$ long=12345678901234567890
    1.55 +.sp .3
    1.56 +	$ echo "$long" | cut -c -10
    1.57 +	1234567890
    1.58 +.CE
    1.59 +.LP
    1.60 +Dieser Befehl gibt die ersten maximal 10 Zeichen von
    1.61 +\f(CW$long\fP aus. (Alternativ kann man hierfür \f(CWprintf
    1.62 +"%.10s\\n" "$long"\fP verwenden.)
    1.63 +.PP
    1.64 +Geht es aber nicht um die Darstellung von Zeichen, sondern um
    1.65 +ihre Speicherung, dann ist \f(CW-c\fP nur bedingt geeignet.
    1.66 +Früher, als US-ASCII noch die omnipräsente Zeichenkodierung
    1.67 +war, wurde jedes Zeichen mit genau einem
    1.68 +Byte gespeichert. Somit selektierte \f(CWcut -c\fP gleichermaßen
    1.69 +sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
    1.70 +Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
    1.71 +dieser Annahme lösen. In diesem Zug bekam cut mit
    1.72 +POSIX.2-1992 einen Bytemodus (Option \f(CW-b\fP). Will man
    1.73 +also nur die ersten maximal 500 Bytes vor dem
    1.74 +Newline-Zeichen stehen haben (und den Rest stillschweigend
    1.75 +ignorieren), dann macht man das mit:
    1.76 +.CS
    1.77 +	$ cut -b -500
    1.78 +.CE
    1.79 +.LP
    1.80 +Den Rest kann man sich mit \f(CWcut -b 501-\fP einfangen. Diese
    1.81 +Funktion ist insbesondere für POSIX wichtig, da man damit
    1.82 +Textdateien mit begrenzter Zeilenlänge erzeugen kann
    1.83 +.[[ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17 .
    1.84 +.PP
    1.85 +Wenn auch der Bytemodus neu eingeführt worden war, so sollte
    1.86 +er sich doch nur so verhalten wie der alte Zeichenmodus
    1.87 +normalerweise schon implementiert war. Beim Zeichenmodus wurde
    1.88 +dagegen eine neue Implementierungsweise gefordert. Das Problem
    1.89 +war folglich nicht, den neuen Bytemodus zu implementieren, sondern
    1.90 +den Zeichenmodus neu zu implementieren.
    1.91 +.PP
    1.92 +Neben dem Zeichen- und Bytemodus bietet cut noch den
    1.93 +Feldmodus, den man mit \f(CW-f\fP einleitet. Mit ihm
    1.94 +können Felder ausgewählt werden. Das Trennzeichen (per
    1.95 +Default der Tab) kann mit \f(CW-d\fP geändert werden. Es gilt in
    1.96 +gleicher Weise für die Eingabe und die Ausgabe.
    1.97 +.PP
    1.98 +Der typische Anwendungsfall für cut im Feldmodus ist die
    1.99 +Auswahl von Information aus der passwd-Datei. Hier z.B. der
   1.100 +Benutzername und seine ID:
   1.101 +.CS
   1.102 +	$ cut -d: -f1,3 /etc/passwd
   1.103 +	root:0
   1.104 +	bin:1
   1.105 +	daemon:2
   1.106 +	mail:8
   1.107 +	...
   1.108 +.CE
   1.109 +.LP
   1.110 +(Die Argumente für die Optionen können bei cut übrigens
   1.111 +sowohl mit Whitespace abgetrennt als auch direkt angehängt folgen.)
   1.112 +.PP
   1.113 +Dieser Feldmodus ist für einfache tabellarische Dateien,
   1.114 +wie eben die passwd, gut geeignet. Er kommt aber schnell an
   1.115 +seine Grenzen. Gerade der häufige Fall, dass an Whitespace
   1.116 +in Felder geteilt werden soll, wird damit nicht abgedeckt.
   1.117 +Der Delimiter kann bei cut nur genau ein Zeichen sein. Es kann
   1.118 +demnach nicht sowohl an Leerzeichen als auch an Tabs aufgetrennt
   1.119 +werden. Zudem unterteilt cut an jedem Trennzeichen. Zwei aneinander
   1.120 +stehende Trennzeichen führen zu einem leeren Feld. Dieses
   1.121 +Verhalten widerspricht den Erwartungen, die man an die
   1.122 +Verarbeitung einer Datei mit Whitespace-getrennten Feldern
   1.123 +hat. Manche Implementierungen von cut, z.B. die von FreeBSD,
   1.124 +haben deshalb Erweiterungen, die das gewünschte Verhalten
   1.125 +für Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn
   1.126 +man portabel bleiben will, verwendet man awk in diesen
   1.127 +Fällen.
   1.128 +.PP
   1.129 +Awk bietet noch eine weitere Funktion, die cut missen
   1.130 +lässt: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei
   1.131 +cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein
   1.132 +Feld kann selbst mehrfach angegeben werden. Dementsprechend gibt
   1.133 +der Aufruf
   1.134 +von \f(CWcut -c 5-8,1,4-6\fP die Zeichen Nummer 1, 4, 5, 6, 7 und 8
   1.135 +in genau dieser Reihenfolge aus. Die Auswahl entspricht damit
   1.136 +der Mengenlehre in der Mathematik: Jedes angegebene Feld wird
   1.137 +Teil der Ergebnismenge. Die Felder der Ergebnismenge sind
   1.138 +hierbei immer gleich geordnet wie in der Eingabe. Um die Worte
   1.139 +der Manpage von Version 8 Unix wiederzugeben: ``In data base
   1.140 +parlance, it projects a relation.''
   1.141 +.[[ http://man.cat-v.org/unix_8th/1/cut
   1.142 +Cut führt demnach die Datenbankoperation Projektion auf
   1.143 +Textdateien aus. Die Wikipedia
   1.144 +erklärt das folgendermaßen:
   1.145 +.QP
   1.146 +Die Projektion entspricht der Projektionsabbildung aus der
   1.147 +Mengenlehre und kann auch Attributbeschränkung genannt
   1.148 +werden. Sie extrahiert einzelne Attribute aus der
   1.149 +ursprünglichen Attributmenge und ist somit als eine Art
   1.150 +Selektion auf Spaltenebene zu verstehen, das heißt, die
   1.151 +Projektion blendet Spalten aus. 
   1.152 +.[[ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
   1.153 +
   1.154 +.SH
   1.155 +Geschichtliches
   1.156 +.LP
   1.157 +Cut erblickte 1982 mit dem Release von UNIX System III das
   1.158 +Licht der öffentlichen Welt. Wenn man die Quellen von System
   1.159 +III durchforstet, findet man cut.c mit dem Zeitstempel 1980-04-11
   1.160 +.[[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd .
   1.161 +Das ist die älteste Implementierung des Programms, die ich
   1.162 +aufstöbern konnte. Allerdings spricht die SCCS-ID im
   1.163 +Quellcode von Version 1.5. Die Vorgeschichte liegt, der Vermutung
   1.164 +Doug McIlroys
   1.165 +.[[ http://minnie.tuhs.org/pipermail/tuhs/2015-May/004083.html
   1.166 +zufolge, in PWB/UNIX, dessen Entwicklungslinie die Grundlage für
   1.167 +System III war. In den von PWB 1.0 (1977) verfügbaren Quellen
   1.168 +.[[ http://minnie.tuhs.org/Archive/PDP-11/Distributions/usdl/
   1.169 +ist cut noch nicht zu finden. Von PWB 2.0 scheinen keine
   1.170 +Quellen oder hilf\%reiche Dokumentation verfügbar zu sein.
   1.171 +PWB 3.0 wurde später aus Marketinggründen als System III
   1.172 +bezeichnet und ist folglich mit ihm identisch. Eine Nebenlinie zu
   1.173 +PWB war CB UNIX, das nur innerhalb
   1.174 +der Bell Labs genutzt wurde. Das Handbuch von CB UNIX Edition 2.1
   1.175 +vom November 1979 enthält die früheste Erwähnung von cut, die
   1.176 +meine Recherche zutage gefördert hat: eine Manpage für cut
   1.177 +.[[ ftp://sunsite.icm.edu.pl/pub/unix/UnixArchive/PDP-11/Distributions/other/CB_Unix/cbunix_man1_02.pdf .
   1.178 +.PP
   1.179 +Nun ein Blick auf die BSD-Linie: Dort ist der früheste
   1.180 +Fund ein cut.c mit dem Dateimodifikationsdatum 1986-11-07
   1.181 +.[[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
   1.182 +als Teil der Spezialversion 4.3BSD-UWisc
   1.183 +.[[ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix ,
   1.184 +die im Januar 1987 veröffentlicht wurde.
   1.185 +Die Implementierung unterscheidet sich nur minimal von der
   1.186 +in System III.
   1.187 +Im bekannteren 4.3BSD-Tahoe (1988) tauchte cut nicht auf.
   1.188 +Das darauf folgende 4.3BSD-Reno (1990) lieferte aber wieder
   1.189 +ein cut mit aus. Dieses cut war ein von Adam S. Moskowitz und
   1.190 +Marciano Pitargue neu implementiertes cut, das 1989 in BSD
   1.191 +aufgenommen wurde
   1.192 +.[[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut .
   1.193 +Seine Manpage
   1.194 +.[[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
   1.195 +erwähnt bereits die erwartete Konformität mit POSIX.2.
   1.196 +Nun muss man wissen, dass POSIX.2 erst im September
   1.197 +1992 veröffentlicht wurde, erst gut zwei Jahren nachdem die
   1.198 +Manpage und das Programm geschrieben worden waren. Das Programm
   1.199 +wurde folglich anhand von Arbeitsversionen des Standards
   1.200 +implementiert. Ein Blick in den Code bekräftigt diese Vermutung.
   1.201 +In der Funktion zum Parsen der Feldauswahlliste findet sich
   1.202 +dieser Kommentar:
   1.203 +.QP
   1.204 +This parser is less restrictive than the Draft 9 POSIX spec.
   1.205 +POSIX doesn't allow lists that aren't in increasing order or
   1.206 +overlapping lists.
   1.207 +.LP
   1.208 +Im Draft 11.2 (1991-09) fordert POSIX diese Flexibilität bereits
   1.209 +ein:
   1.210 +.QP
   1.211 +The elements in list can be repeated, can overlap, and can
   1.212 +be specified in any order.
   1.213 +.LP
   1.214 +Zudem listet Draft 11.2 alle drei Modi, während in diesem
   1.215 +BSD cut nur die zwei alten implementiert sind. Es könnte also
   1.216 +sein, dass in Draft 9 der Bytemodus noch nicht vorhanden war.
   1.217 +Ohne Zugang zu Draft 9 oder 10, war es leider nicht möglich,
   1.218 +diese Vermutung zu prüfen.
   1.219 +.PP
   1.220 +Die Versionsnummern und Änderungsdaten der älteren
   1.221 +BSD-Implementierungen kann man aus den SCCS-IDs, die vom
   1.222 +damaligen Versionskontrollsystem in den Code eingefügt wurden,
   1.223 +ablesen. So z.B. bei 4.3BSD-Reno: ``5.3 (Berkeley) 6/24/90''.
   1.224 +.PP
   1.225 +Das cut der GNU Coreutils enthält folgenden Copyrightvermerk:
   1.226 +.CS
   1.227 +	Copyright (C) 1997-2015 Free Software Foundation, Inc.
   1.228 +	Copyright (C) 1984 David M. Ihnat
   1.229 +.CE
   1.230 +.LP
   1.231 +Der Code hat also recht alte Ursprünge. Wie aus weiteren
   1.232 +Kommentaren zu entnehmen ist, wurde der Programmcode zuerst von David
   1.233 +MacKenzie und später von Jim Meyering überarbeitet. Letzterer
   1.234 +hat den Code 1992 auch ins Versionkontrollsystem eingestellt.
   1.235 +Weshalb die Jahre vor 1997, zumindest ab 1992, nicht im
   1.236 +Copyright-Vermerk auftauchen, ist unklar.
   1.237 +.PP
   1.238 +Trotz der vielen Jahreszahlen aus den 80er Jahren gehört cut,
   1.239 +aus Sicht des ursprünglichen Unix, zu den jüngeren Tools.
   1.240 +Wenn cut auch ein Jahrzehnt älter als Linux, der Kernel, ist,
   1.241 +so war Unix schon über zehn Jahre alt, als cut das
   1.242 +erste Mal auftauchte. Insbesondere gehörte cut noch nicht
   1.243 +zu Version 7 Unix, das die Ausgangsbasis aller modernen
   1.244 +Unix-Systeme darstellt. Die weit komplexeren Programme sed
   1.245 +und awk waren dort aber schon vertreten. Man muss sich also
   1.246 +fragen, warum cut überhaupt noch entwickelt wurde, wo es
   1.247 +schon zwei Programme gab, die die Funktion von cut abdecken
   1.248 +konnten. Ein Argument für cut war sicher seine Kompaktheit und
   1.249 +die damit verbundene Geschwindigkeit gegenüber dem damals
   1.250 +trägen awk. Diese schlanke Gestalt ist es auch, die der
   1.251 +Unix-Philosopie entspricht: Mache eine Aufgabe und die richtig!
   1.252 +Cut überzeugte. Es wurde in andere Unix Varianten übernommen,
   1.253 +stan\%dard\%isiert und ist heutzutage überall anzutreffen.
   1.254 +.PP
   1.255 +Die ursprüngliche Variante (ohne \f(CW-b\fP) wurde schon 1985 in
   1.256 +der System V Interface Definition, einer wichtigen formalen
   1.257 +Beschreibung von UNIX System V, spezifiziert und tauchte
   1.258 +anschließend in allen relevanten Standards auf. Mit POSIX.2
   1.259 +im Jahre 1992 wurde cut zum ersten Mal in der heutigen Form
   1.260 +(mit \f(CW-b\fP) standardisiert.
   1.261 +
   1.262 +.SH
   1.263 +Multibyte-Unterstützung
   1.264 +.LP
   1.265 +Nun sind der Bytemodus und die damit verbundene
   1.266 +Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit
   1.267 +1992 standardisiert, wie steht es aber mit deren Umsetzung?
   1.268 +Welche Versionen implementieren POSIX korrekt?
   1.269 +Die Situation ist dreiteilig: Es gibt historische
   1.270 +Implementierungen, die nur \f(CW-c\fP und \f(CW-f\fP kennen. Dann gibt es
   1.271 +Implementierungen die \f(CW-b\fP zwar kennen, es aber lediglich als Alias
   1.272 +für \f(CW-c\fP handhaben. Diese Implementierungen funktionieren mit
   1.273 +Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei
   1.274 +Multibyte-Encodings (z.B. UTF-8) verhält sich ihr \f(CW-c\fP aber
   1.275 +wie \f(CW-b\fP (und \f(CW-n\fP wird ignoriert). Schließlich gibt es noch
   1.276 +Implementierungen, die \f(CW-b\fP und \f(CW-c\fP tatsächlich POSIX-konform
   1.277 +implementieren.
   1.278 +.PP
   1.279 +Historische Zwei-Modi-Implementierungen sind die von
   1.280 +System III, System V und die aller BSDs bis in die 90er.
   1.281 +.PP
   1.282 +Pseudo-Multibyte-Implementierungen bieten GNU und die
   1.283 +modernen NetBSDs und OpenBSDs. Man darf sich sicher fragen,
   1.284 +ob dort ein Schein von POSIX-Konformität gewahrt wird.
   1.285 +Teilweise findet man erst nach genauerer Suche heraus, dass
   1.286 +\f(CW-c\fP und \f(CW-n\fP nicht wie erwartet funktionieren; teilweise machen es
   1.287 +sich die Systeme auch einfach, indem sie auf
   1.288 +Singlebyte-Zeichenkodierungen beharren, das aber dafür
   1.289 +klar darlegen:
   1.290 +.QP
   1.291 +Since we don't support multi-byte characters, the \f(CW-c\fP and \f(CW-b\fP
   1.292 +options are equivalent, and the \f(CW-n\fP option is meaningless.
   1.293 +.[[ http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/cut/cut.c?rev=1.18&content-type=text/x-cvsweb-markup
   1.294 +.LP
   1.295 +Tatsächlich standardkonforme Implementierungen, die
   1.296 +Multibytes korrekt handhaben, bekommt man bei einem modernen
   1.297 +FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins
   1.298 +im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert
   1.299 +.[[ https://svnweb.freebsd.org/base?view=revision&revision=131194 .
   1.300 +Warum die beiden anderen großen BSDs diese Änderung nicht
   1.301 +übernommen haben, bleibt offen. Es scheint aber an der im
   1.302 +obigen Kommentar formulierten Grundausrichtung zu liegen.
   1.303 +.PP
   1.304 +Wie findet man nun als Nutzer heraus, ob beim cut des eigenen
   1.305 +Systems Multibytes korrekt unterstützt werden? Zuerst ist
   1.306 +entscheidend, ob das System selbst mit einem Multibyte-Encoding
   1.307 +arbeitet, denn tut es das nicht, dann entsprechen sich
   1.308 +Zeichen und Bytes und die Frage erübrigt sich. Man kann das
   1.309 +herausfinden indem man sich das Locale anschaut, aber einfacher
   1.310 +ist es, ein typisches Mehrbytezeichen, wie z.B. einen Umlaut,
   1.311 +auszugeben und zu schauen ob dieses in einem oder in mehreren
   1.312 +Bytes kodiert ist:
   1.313 +.CS
   1.314 +	$ echo ä | od -c
   1.315 +	0000000 303 244  \\n
   1.316 +	0000003
   1.317 +.CE
   1.318 +.LP
   1.319 +In diesem Fall sind es zwei Bytes: oktal 303 und 244. (Den
   1.320 +Zeilenumbruch fügt echo hinzu.)
   1.321 +.PP
   1.322 +Mit dem Programm iconv kann man Text explizit in bestimmte
   1.323 +Kodierungen konvertieren. Hier Beispiele, wie die Ausgabe
   1.324 +bei Latin1 und wie sie bei UTF-8 aussieht:
   1.325 +.CS
   1.326 +	$ echo ä | iconv -t latin1 | od -c        
   1.327 +	0000000 344  \\n
   1.328 +	0000002
   1.329 +.sp .3
   1.330 +	$ echo ä | iconv -t utf8 | od -c  
   1.331 +	0000000 303 244  \\n
   1.332 +	0000003
   1.333 +.CE
   1.334 +.LP
   1.335 +Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung)
   1.336 +wird recht sicher einer dieser beiden Ausgaben entsprechen.
   1.337 +.PP
   1.338 +Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System,
   1.339 +dann sollte sich eine POSIX-konforme Implementierung folgendermaßen
   1.340 +verhalten:
   1.341 +.CS
   1.342 +	$ echo ä | cut -c 1 | od -c
   1.343 +	0000000 303 244  \\n
   1.344 +	0000003
   1.345 +.sp .3
   1.346 +	$ echo ä | cut -b 1 | od -c
   1.347 +	0000000 303  \\n
   1.348 +	0000002
   1.349 +.sp .3
   1.350 +	$ echo ä | cut -b 1 -n | od -c
   1.351 +	0000000  \\n
   1.352 +	0000001
   1.353 +.CE
   1.354 +.LP
   1.355 +Bei einer Pseudo-POSIX-Implementierung ist die Ausgabe in
   1.356 +allen drei Fällen wie die mittlere: Es wird das erste Byte
   1.357 +ausgegeben.
   1.358 +
   1.359 +.SH
   1.360 +Implementierungen
   1.361 +.LP
   1.362 +Nun ein Blick auf den Code. Betrachtet wird eine Auswahl an
   1.363 +Implementierungen.
   1.364 +.PP
   1.365 +Für einen ersten Eindruck ist der Umfang des Quellcodes
   1.366 +hilfreich. Typischerweise steigt dieser über die Jahre an. Diese
   1.367 +Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall,
   1.368 +bestätigt werden. Die POSIX-konforme Umsetzung des Zeichenmodus
   1.369 +erfordert zwangsläufig mehr Code, deshalb sind diese
   1.370 +Implementierungen tendenziell umfangreicher.
   1.371 +.TS
   1.372 +center;
   1.373 +r r r l l l.
   1.374 +SLOC	Zeilen	Bytes	Gehört zu  	Dateidatum	Kategorie
   1.375 +_
   1.376 +116	123	 2966	System III	1980-04-11	historisch
   1.377 +118	125	 3038	4.3BSD-UWisc	1986-11-07	historisch
   1.378 +200	256	 5715	4.3BSD-Reno	1990-06-25	historisch
   1.379 +200	270	 6545	NetBSD	1993-03-21	historisch
   1.380 +218	290	 6892	OpenBSD	2008-06-27	pseudo-POSIX
   1.381 +224	296	 6920	FreeBSD	1994-05-27	historisch
   1.382 +232	306	 7500	NetBSD 	2014-02-03	pseudo-POSIX
   1.383 +340	405	 7423	Heirloom	2012-05-20	POSIX
   1.384 +382	586	14175	GNU coreutils	1992-11-08	pseudo-POSIX
   1.385 +391	479	10961	FreeBSD	2012-11-24	POSIX
   1.386 +588	830	23167	GNU coreutils	2015-05-01	pseudo-POSIX
   1.387 +.TE
   1.388 +.LP
   1.389 +Das Kandidatenfeld teilt sich grob in vier Gruppen: (1) Die zwei
   1.390 +ursprünglichen Implementierungen, die sich nur minimal
   1.391 +unterscheiden, mit gut 100 SLOCs. (2) Die fünf BSD-Versionen mit
   1.392 +gut 200 SLOCs. (3) Die zwei POSIX-konformen Programme und
   1.393 +die alte GNU-Version mit 340\(en390 SLOCs. Und schließlich (4) die
   1.394 +moderne GNU-Variante mit fast 600 SLOCs.
   1.395 +.PP
   1.396 +Die Abweichung zwischen logischen Codezeilen (SLOC, ermittelt mit
   1.397 +SLOCcount) und der Anzahl von Zeilenumbrüchen in der Datei (\f(CWwc
   1.398 +-l\fP) erstreckt sich über eine Spanne von Faktor 1,06 bei den
   1.399 +ältesten Vertretern bis zu Faktor 1,5 bei GNU. Den größten
   1.400 +Einfluss darauf haben Leerzeilen, reine Kommentarzeilen und
   1.401 +die Größe des Lizenzblocks am Dateianfang. 
   1.402 +.PP
   1.403 +Betrachtet man die Abweichungen zwischen den logischen Codezeilen
   1.404 +und der Dateigröße (\f(CWwc -c\fP), so pendelt das Teilnehmerfeld
   1.405 +zwischen 25 und 30 Bytes je Anweisung. Die Heirloom-Implementierung
   1.406 +weicht mit nur 21 nach unten ab, die GNU-Implementierungen mit
   1.407 +fast 40 nach oben. Bei GNU liegt dies hauptsächlich an deren
   1.408 +Programmierstil, mit spezieller Einrückung und langen Bezeichnern.
   1.409 +Ob man die Heirloom-Implementierung
   1.410 +.[[ http://heirloom.cvs.sourceforge.net/viewvc/heirloom/heirloom/cut/cut.c?revision=1.6&view=markup
   1.411 +als besonders kryptisch
   1.412 +oder als besonders elegant bezeichnen will, das soll der
   1.413 +eigenen Einschätzung des Lesers überlassen bleiben. Vor allem
   1.414 +der Vergleich mit einer GNU-Implementierung
   1.415 +.[[ http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/cut.c;hb=e981643
   1.416 +ist eindrucksvoll.
   1.417 +.PP
   1.418 +Die interne Struktur der Programmcodes (in C) ist meist ähnlich.
   1.419 +Neben der obligatorischen main-Funktion, die die Kommandozeilenargumente
   1.420 +verarbeitet, gibt es im Normalfall eine Funktion, die die
   1.421 +Feldauswahl in eine interne Datenstruktur überführt. Desweiteren
   1.422 +haben fast alle Implementierungen separate Funktionen für jeden
   1.423 +ihrer Modi. Bei den POSIX-konformen Implementierungen
   1.424 +wird die \f(CW-b -n\fP-Kombination als weiterer Modus behandelt, und
   1.425 +damit in einer eigenen Funktion umgesetzt. Nur bei der frühen
   1.426 +System III-Implementierung (und seiner 4.3BSD-UWisc-Variante)
   1.427 +wird außer den Fehlerausgaben alles in der main-Funktion
   1.428 +erledigt.
   1.429 +.PP
   1.430 +Cut-Implementierungen haben typischerweise zwei limitierende
   1.431 +Größen: Die Maximalanzahl unterstützter Felder und die maximale
   1.432 +Zeilenlänge. Bei System III sind beide Größen auf 512 begrenzt.
   1.433 +4.3BSD-Reno und die BSDs der 90er Jahre haben ebenfalls fixe
   1.434 +Grenzen (\f(CW_BSD_LINE_MAX\fP bzw. \f(CW_POSIX2_LINE_MAX\fP). Bei modernen
   1.435 +FreeBSDs, NetBSDs, bei allen GNU-Implementierungen und bei
   1.436 +Heirloom kann sowohl die Felderanzahl als auch die maximale
   1.437 +Zeilenlänge beliebig groß werden; der Speicher dafür wird
   1.438 +dynamisch alloziiert. OpenBSD ist ein Hybrid aus fixer
   1.439 +Maximalzahl an Feldern und beliebiger Zeilenlänge. Die
   1.440 +begrenzte Felderanzahl scheint jedoch kein Praxisproblem
   1.441 +darzustellen, da \f(CW_POSIX2_LINE_MAX\fP mit mindestens 2048 durchaus
   1.442 +groß genug sein sollte.
   1.443 +
   1.444 +.SH
   1.445 +Beschreibungen
   1.446 +.LP
   1.447 +Interessant ist zudem ein Vergleich der Kurzbeschreibungen von
   1.448 +cut, wie sie sich in der Titelzeile der Manpages oder manchmal
   1.449 +am Anfang der Quellcodedatei finden. Die folgende Liste
   1.450 +ist grob zeitlich geordnet und nach Abstammung gruppiert:
   1.451 +.TS
   1.452 +center;
   1.453 +l l.
   1.454 +CB UNIX	cut out selected fields of each line of a file
   1.455 +System III	cut out selected fields of each line of a file
   1.456 +System III \(dg	cut and paste columns of a table (projection of a relation)
   1.457 +System V	cut out selected fields of each line of a file
   1.458 +HP-UX	cut out (extract) selected fields of each line of a file
   1.459 +.sp .3
   1.460 +4.3BSD-UWisc \(dg	cut and paste columns of a table (projection of a relation)
   1.461 +4.3BSD-Reno	select portions of each line of a file
   1.462 +NetBSD	select portions of each line of a file
   1.463 +OpenBSD 4.6	select portions of each line of a file
   1.464 +FreeBSD 1.0	select portions of each line of a file
   1.465 +FreeBSD 10.0	cut out selected portions of each line of a file
   1.466 +SunOS 4.1.3	remove selected fields from each line of a file
   1.467 +SunOS 5.5.1	cut out selected fields of each line of a file
   1.468 +.sp .3
   1.469 +Heirloom Tools	cut out selected fields of each line of a file
   1.470 +Heirloom Tools \(dg	cut out fields of lines of files
   1.471 +.sp .3
   1.472 +GNU coreutils	remove sections from each line of files
   1.473 +.sp .3
   1.474 +Minix	select out columns of a file
   1.475 +.sp .3
   1.476 +Version 8 Unix	rearrange columns of data
   1.477 +``Unix Reader''	rearrange columns of text
   1.478 +.sp .3
   1.479 +POSIX	cut out selected fields of each line of a file
   1.480 +.TE
   1.481 +.LP
   1.482 +Die mit `\(dg' markierten Beschreibungen sind aus dem
   1.483 +jeweiligen Quellcode entnommen. Der POSIX-Eintrag enthält
   1.484 +die Beschreibung im Standard. Der ``Unix Reader'' ist ein
   1.485 +rückblickendes Textdokument von Doug McIlroy, das das
   1.486 +Auftreten der Tools in der Geschichte des Research Unix zum
   1.487 +Thema hat
   1.488 +.[[ http://doc.cat-v.org/unix/unix-reader/contents.pdf .
   1.489 +Eigentlich sollte seine Beschreibung der in Version 8 Unix
   1.490 +entsprechen. Die Abweichung könnte ein Übertragungsfehler
   1.491 +oder eine nachträgliche Korrektur sein. Alle übrigen
   1.492 +Beschreibungen entstammen den Manpages.
   1.493 +.PP
   1.494 +Oft ist mit der Zeit die POSIX-Beschreibung übernommen
   1.495 +oder an sie angeglichen worden, wie beispielsweise bei FreeBSD
   1.496 +.[[ https://svnweb.freebsd.org/base?view=revision&revision=167101 .
   1.497 +.PP
   1.498 +Interessant ist, dass die GNU coreutils seit Anbeginn vom
   1.499 +Entfernen von Teilen der Eingabe sprechen, wohingegen die
   1.500 +Kommandozeilenangabe klar ein Auswählen darstellt. Die
   1.501 +Worte ``cut out'' sind vielleicht auch zu missverständlich.
   1.502 +HP-UX hat sie deshalb präzisiert.
   1.503 +.PP
   1.504 +Beim Begriff, was selektiert wird, ist man sich ebenfalls
   1.505 +uneins. Die Einen reden von Feldern (POSIX), Andere von
   1.506 +Abschnitten bzw. Teilen (BSD) und wieder Andere von Spalten
   1.507 +(Research Unix).
   1.508 +.PP
   1.509 +Die scheinbar unzutreffende Beschreibung
   1.510 +bei Version 8 Unix (``rearrange columns of data'') ist
   1.511 +dadurch zu erklären, dass die Manpage sowohl cut als auch
   1.512 +paste abdeckt. In ihrer Kombination können tatsächlich
   1.513 +Spalten umgeordnet werden.
   1.514 +
   1.515 +.SH
   1.516 +Referenzen
   1.517 +.LP
   1.518 +.nf
   1.519 +._r
   1.520 +