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 +