docs/cut

diff cut.txt @ 8:1dc4a9dca829

Zwischenstand
author markus schnalke <meillo@marmaro.de>
date Tue, 05 May 2015 09:04:00 +0200
parents 21ca59543b07
children e67bd0d48bd6
line diff
     1.1 --- a/cut.txt	Sun May 03 21:05:00 2015 +0200
     1.2 +++ b/cut.txt	Tue May 05 09:04:00 2015 +0200
     1.3 @@ -7,23 +7,22 @@
     1.4  
     1.5  
     1.6  Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
     1.7 -In keinem ordentlichen Tutorial zur Shellprogrammierung darf
     1.8 -es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt
     1.9 -fuer's Shellscripting. Hier will ich ein wenig hinter die
    1.10 -Fassade schauen.
    1.11 +In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt
    1.12 +es. Es ist ein schoenes Anschauungsobjekt fuer's Shellscripting.
    1.13 +Hier soll ein wenig hinter die Fassade von cut geschaut werden.
    1.14  
    1.15  
    1.16  Funktionsweise
    1.17  
    1.18 -Die Funktionsbasis von cut waren urspruenglich zwei Modi, die
    1.19 -spaeter um einen dritten erweitert wurden. Cut schneidet
    1.20 -entweder bestimmte Zeichen aus den Zeilen der Eingabe oder
    1.21 -bestimmte durch Trennzeichen definierte Felder.
    1.22 +Urspruenglich hatte cut zwei Modi, die spaeter um einen dritten
    1.23 +erweitert wurden. Cut schneidet entweder bestimmte Zeichen aus
    1.24 +den Zeilen der Eingabe oder bestimmte, durch Trennzeichen
    1.25 +definierte, Felder.
    1.26  
    1.27 -Der Zeichenmodus ist geeignet um Ausschnitte aus
    1.28 -Festbreitenformaten zu extrahieren. So kann man damit
    1.29 -beispielsweise bestimmte Zugriffsrechte aus der Ausgabe von
    1.30 -`ls -l' ausschneiden. Hier die Rechte des Besitzers:
    1.31 +Der Zeichenmodus ist geeignet um Festbreitenformaten zu
    1.32 +zerteilen. So kann man damit beispielsweise bestimmte
    1.33 +Zugriffsrechte aus der Ausgabe von `ls -l' ausschneiden. Hier
    1.34 +die Rechte des Besitzers:
    1.35  
    1.36  	$ ls -l foo | cut -c 2-4
    1.37  	rw-
    1.38 @@ -38,18 +37,19 @@
    1.39  
    1.40  	$ echo "$long" | cut -c -20
    1.41  
    1.42 -Dieser Befehl gibt die ersten maximal 20 Zeichen (jeder
    1.43 -Zeile) von `$long' aus.
    1.44 +Dieser Befehl gibt die ersten maximal 20 Zeichen von
    1.45 +`$long' aus. (Alternativ kann man hierfuer auch `printf
    1.46 +"%.20s\n" "$long"' verwenden.)
    1.47  
    1.48  Geht es aber nicht um die Darstellung von Zeichen, sondern um
    1.49 -ihre Speicherung, dann ist `-c' nicht unbedingt die passende
    1.50 -Option. Frueher, als US-ASCII als Zeichensatz und -kodierung
    1.51 +ihre Speicherung, dann ist `-c' nicht unbedingt geeignet.
    1.52 +Frueher, als US-ASCII als Zeichensatz und -kodierung
    1.53  noch omnipraesent war, wurde jedes Zeichen mit genau einem
    1.54  Byte gespeichert. Somit selektierte `cut -c' gleichermassen
    1.55  sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
    1.56  Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
    1.57  dieser Annahme loesen. In diesem Zug bekam cut mit
    1.58 -POSIX.2-1992 die Option `-b'. Diese selektiert Bytes. Will man
    1.59 +POSIX.2-1992 einen Bytemodus mit der Option `-b'. Will man
    1.60  also nur die ersten maximal 500 Bytes vor dem
    1.61  Newline-Zeichen stehen haben (und den Rest stillschweigend
    1.62  ignorieren), dann macht man das mit:
    1.63 @@ -57,24 +57,23 @@
    1.64  	$ cut -b -500
    1.65  
    1.66  Den Rest kann man sich mit `cut -b 501-' einfangen. Diese
    1.67 -Funktion ist insbesondere fuer POSIX wichtig, da so sicher
    1.68 -gestellt werden kann, dass Textdateien keine beliebig
    1.69 -langen Zeilen haben.
    1.70 +Funktion ist insbesondere fuer POSIX wichtig, da man so
    1.71 +Textdateien mit begrenzter Zeilenlaenge erzeugen kann.
    1.72  [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17
    1.73  
    1.74  Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den
    1.75 -interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm
    1.76 +Feld-Modus, den man mit `-f' einleitet. Mit ihm
    1.77  koennen Felder ausgewaehlt werden. Das Trennzeichen (per
    1.78  Default der Tab) kann mit `-d' geaendert werden.
    1.79  
    1.80 -Der typische Anwendungsfall fuer den Feld-Modus. Ist die
    1.81 -Extraktion von Information aus der passwd-Datei. So z.B. der
    1.82 -Username, die User-ID und das Homeverzeichnis:
    1.83 +Der typische Anwendungsfall fuer cut im Feld-Modus ist die
    1.84 +Auswahl von Information aus der passwd-Datei. So z.B. der
    1.85 +Benutername, seine ID und das Homeverzeichnis:
    1.86  
    1.87  	$ cut -d: -f1,3,6 /etc/passwd
    1.88  
    1.89  (Die Argumente fuer die Optionen koennen bei cut uebrigens
    1.90 -direkt angehaengt oder mit Whitespace abgetrennt folgen.)
    1.91 +mit Whitespace abgetrennt oder direkt angehaengt folgen.)
    1.92  
    1.93  
    1.94  Dieser Feld-Modus ist fuer einfache tabellarische Dateien,
    1.95 @@ -85,30 +84,27 @@
    1.96  nicht sowohl an Leerzeichen als auch an Tabs getrennt werden.
    1.97  Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander
    1.98  stehende Trennzeichen fuehren zu einem leeren Feld. Dieses
    1.99 -Verhalten widerspricht den Erwartungen fuer eine Datei mit
   1.100 -Whitespace-getrennten Feldern. (Manche Implementierungen von
   1.101 -cut, z.B. die von FreeBSD, haben deshalb Erweiterungen, die
   1.102 -das gewuenschte Verhalten fuer Whitespace-getrennte Felder
   1.103 -bieten.) Ansonsten, d.h. wenn man portabel bleiben will,
   1.104 -hilft awk.
   1.105 +Verhalten widerspricht den Erwartungen, die man an die
   1.106 +Verarbeitung einer Datei mit Whitespace-getrennten Feldern
   1.107 +hat. Manche Implementierungen von cut, z.B. die von FreeBSD,
   1.108 +haben Erweiterungen, die das gewuenschte Verhalten fuer
   1.109 +Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn
   1.110 +man portabel bleiben will, hilft awk.
   1.111  
   1.112  Awk bietet noch eine weitere Funktion, die cut missen
   1.113 -laesst: Das Tauschen der Felder-Reihenfolge. Bei cut ist die
   1.114 -Reihenfolge der Feldauswahl irrelevant; ein Feld kann selbst
   1.115 -mehrfach angegeben werden. Der Aufruf von `cut -c 5-8,1,4-6'
   1.116 -gibt z.B.  die Zeichen Nummer 1, 4, 5, 6, 7 und 8 aus. Die
   1.117 -Auswahl aehnelt damit der Mengenlehre in der Mathematik:
   1.118 -Jedes angegebene Feld soll in der Ergebnismenge sein. Die
   1.119 -Felder der Ergebnismenge werden dabei immer in der gleichen
   1.120 -Reihenfolge ausgegeben wie sie in der Eingabe waren.
   1.121 -
   1.122 -
   1.123 -
   1.124 -cut(1) in Version 8 Unix
   1.125 -``In data base parlance, it projects a relation.''
   1.126 -
   1.127 -WP:
   1.128 -http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
   1.129 +laesst: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei
   1.130 +cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein
   1.131 +Feld kann selbst mehrfach angegeben werden. So gibt der Aufruf
   1.132 +von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8
   1.133 +in genau dieser Reihenfolge aus. Die Auswahl entspricht damit
   1.134 +der Mengenlehre in der Mathematik: Jedes angegebene Feld wird
   1.135 +Teil der Ergebnismenge sein. Die Felder der Ergebnismenge sind
   1.136 +dabei immer gleich geordnet wie sie es in der Eingabe waren.
   1.137 +Oder, um die Worte der Manpage in Version 8 Unix
   1.138 +wiederzugeben: ``In data base parlance, it projects a relation.''
   1.139 +Cut fuehrt also die Datenbankoperation Projektion auf
   1.140 +Textdateien aus. Die Wikipedia erklaert das in
   1.141 +verstaendlicherer Sprache:
   1.142  
   1.143  	Die Projektion entspricht der Projektionsabbildung aus der
   1.144  	Mengenlehre und kann auch Attributbeschränkung genannt
   1.145 @@ -117,6 +113,8 @@
   1.146  	Selektion auf Spaltenebene zu verstehen, das heißt, die
   1.147  	Projektion blendet Spalten aus. 
   1.148  
   1.149 +[ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
   1.150 +
   1.151  
   1.152  
   1.153  
   1.154 @@ -128,30 +126,36 @@
   1.155  Zeitstempel 1980-04-11.
   1.156  [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
   1.157  Das ist die aelteste Manifestation des Programms, die ich
   1.158 -aufstoebern konnte.
   1.159 +aufstoebern konnte. Allerdings spricht die sccsid im
   1.160 +Quellcode von Version 1.5. Es muss also noch eine
   1.161 +Vorgeschichte geben. Zu dieser habe ich leider keinen Zugang
   1.162 +gefunden.
   1.163  
   1.164  Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein
   1.165 -fruehester Fund ein cut.c mit dem Datum 1986-11-07 im Code der
   1.166 -Spezialversion 4.3BSD-UWisc,
   1.167 +fruehester Fund ein cut.c mit dem Dateimodifikationsdatum
   1.168 +1986-11-07
   1.169 +[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
   1.170 +als Teil der Spezialversion 4.3BSD-UWisc,
   1.171  [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
   1.172  die im Januar 1987 veroeffentlicht wurde.
   1.173 -[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
   1.174 -Die Datei unterscheidet sich nur minimal von der aus System III.
   1.175 -Im bekannteren 4.3BSD-Tahoe (1988) taucht cut aber nicht auf.
   1.176 -Im darauf folgenden 4.3BSD-Reno (1990) gibt es wiederum ein
   1.177 -cut ... ein von Adam S. Moskowitz und Marciano Pitargue neu
   1.178 -implementiertes cut, das 1989 in BSD aufgenommen wurde.
   1.179 +Die Implementierung unterscheidet sich nur minimal von der
   1.180 +in System III.
   1.181 +Im bekannteren 4.3BSD-Tahoe (1988) taucht cut nicht auf.
   1.182 +Das darauf folgende 4.3BSD-Reno (1990) liefert aber wieder
   1.183 +ein cut mit aus. Dieses cut ist ein von Adam S. Moskowitz und
   1.184 +Marciano Pitargue neu implementiertes cut, das 1989 in BSD
   1.185 +aufgenommen wurde.
   1.186  [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
   1.187  Seine Manpage
   1.188  [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
   1.189  erwaehnt bereits die erwartete Konformitaet mit POSIX.2.
   1.190  Nun sollte man wissen, dass POSIX.2 erst im September
   1.191 -1992 veroeffentlicht wurde, gut zwei Jahren *nachdem* die
   1.192 -Manpage und das Programm geschrieben wurden. Dieses cut
   1.193 -wurde also anhand von Entwuerfen des Standards
   1.194 +1992 veroeffentlicht wurde, also gut zwei Jahren *nachdem* die
   1.195 +Manpage und das Programm geschrieben wurden. Das Programm
   1.196 +wurde also anhand von Arbeitsversionen des Standards
   1.197  implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in
   1.198  den Standardisierungsprozess geflossen; bis zur
   1.199 -Fertigstellung sollte es noch weitere zwei Jahre dauern.
   1.200 +Fertigstellung sollte es aber noch weitere zwei Jahre dauern.
   1.201  
   1.202  Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut
   1.203  aus Sicht des urspruenglichen Unix zu den juengeren Tools.
   1.204 @@ -162,8 +166,8 @@
   1.205  Unix-Systeme darstellt. Die weit komplexeren Programme sed
   1.206  und awk waren dort schon vertreten. Man muss sich also
   1.207  fragen, warum cut ueberhaupt noch entwickelt wurde, wo es
   1.208 -schon zwei Programme gab, die die Aufgabe von cut bereits
   1.209 -abdeckten. Ein Argument fuer cut ist seine Kompaktheit und
   1.210 +schon zwei Programme gab, die die Aufgabe von cut abdeckten.
   1.211 +Ein Argument fuer cut war sicher seine Kompaktheit und
   1.212  die damit verbundene Geschwindigkeit gegenueber dem damals
   1.213  traegen awk. Diese schlanke Gestalt ist es auch, die der Unix
   1.214  Philosopie entspricht: Mache eine Aufgabe und die richtig!
   1.215 @@ -171,13 +175,200 @@
   1.216  uebernommen, standardisiert und ist heutzutage ueberall
   1.217  anzutreffen.
   1.218  
   1.219 -Die urspruengliche Variante (ohne -b) taucht schon 1985 in
   1.220 +Die urspruengliche Variante (ohne -b) tauchte schon 1985 in
   1.221  der System V Interface Definition, einer wichtigen formalen
   1.222  Beschreibung von UNIX System V, und in allen relevanten
   1.223  Standards seither auf. Mit POSIX.2 im Jahre 1992 wurde cut
   1.224  zum ersten Mal in der heutigen Form (mit -b) standardisiert.
   1.225  
   1.226  
   1.227 +
   1.228 +Multibyte-Behandlung
   1.229 +
   1.230 +Nun sind der Bytemodus und die damit verbundene
   1.231 +Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit
   1.232 +1992 standardisiert, wie steht es aber mit deren Umsetzung?
   1.233 +Welche Versionen implementieren denn den POSIX korrekt?
   1.234 +Die Situation ist mehrschichtig. Es gibt traditionelle
   1.235 +Implementierungen, die nur -c und -f kennen. Dann gibt es
   1.236 +Implementierungen die zwar -b kennen, es aber nur als Alias
   1.237 +fuer -c handhaben. Diese Implementierungen funktionieren mit
   1.238 +Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei
   1.239 +Multi-Byte-Encodings (z.B. UTF-8) verhaelt sich ihr -c aber
   1.240 +wie -b (und -n wird ignoriert). Schliesslich gibt es noch
   1.241 +Implementierungen, die -b und -c tatsaechlich POSIX-konform
   1.242 +implementieren.
   1.243 +
   1.244 +Traditionelle Zwei-Modi-Implementierungen sind z.B. die von
   1.245 +System III, System V und die aller BSDs bis in die 90er.
   1.246 +
   1.247 +Pseude-Multibyte-Implementierungen bieten GNU und die
   1.248 +modernen NetBSDs und OpenBSDs. Wie sehr dort der Schein von
   1.249 +POSIX-konformitaet gewahrt wird, ist unterschiedlich. Nicht
   1.250 +immer findet man klare Aussagen wie diese:
   1.251 +
   1.252 +	/* Since we don't support multi-byte characters, the -c and -b 
   1.253 +	   options are equivalent, and the -n option is meaningless. */
   1.254 +
   1.255 +[ XXX
   1.256 +
   1.257 +Tatsaechlich standardkonforme Implementierungen, die
   1.258 +Multibytes korrekt handhaben, bekommt man bei einem modernen
   1.259 +FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins
   1.260 +(tjr) im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert.
   1.261 +[ https://svnweb.freebsd.org/base?view=revision&revision=131194
   1.262 +Warum die beiden anderen grossen BSDs diese Aenderung nicht
   1.263 +uebernommen haben, bleibt offen. Es scheint aber an der im
   1.264 +obigen Kommentar formulierten Grundausrichtung zu liegen.
   1.265 +
   1.266 +Wie findet man als Nutzer heraus, ob beim cut(1) des eigenen
   1.267 +Systems Multibytes korrekt unterstuetzt werden? Zuerst ist
   1.268 +entscheidend, ob das System selbst mit einem Multibyte-Encoding
   1.269 +arbeitet, denn tut es das nicht, dann entsprechen sich Zeichen
   1.270 +und Bytes und die Frage eruebrigt sich. Man kann dazu nachschauen,
   1.271 +welches Locale eingestellt ist, aber einfacher ist es, ein
   1.272 +typisches Mehrbytezeichen, wie z.B. einen Umlaut, auszugeben
   1.273 +und zu schauen ob dieses in einem oder in mehreren Bytes
   1.274 +kodiert ist:
   1.275 +
   1.276 +	$ echo ä | od -c
   1.277 +	0000000 303 244  \n
   1.278 +	0000003
   1.279 +
   1.280 +In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den
   1.281 +Zeilenumbruch fuegt echo(1) hinzu.)
   1.282 +
   1.283 +Mit dem Programm iconv(1) kann man Test explizit in bestimmte
   1.284 +Kodierungen konvertieren. Hier Beispiele, wie das Ergebnis
   1.285 +bei Latin1 und wie es bei UTF-8 aussieht.
   1.286 +
   1.287 +	$ echo ä | iconv -t latin1 | od -c        
   1.288 +	0000000 344  \n
   1.289 +	0000002
   1.290 +
   1.291 +	$ echo ä | iconv -t utf8 | od -c  
   1.292 +	0000000 303 244  \n
   1.293 +	0000003
   1.294 +
   1.295 +Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung)
   1.296 +wird recht sicher einer dieser beiden Ausgaben entsprechen.
   1.297 +
   1.298 +Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System,
   1.299 +dann sollte sich eine POSIX-konforme Implementierung so verhalten:
   1.300 +
   1.301 +	$ echo aä | ./cut -c -2 | od -c
   1.302 +	0000000   a 303 244  \n
   1.303 +	0000004
   1.304 +
   1.305 +	$ echo aä | ./cut -b -2 | od -c
   1.306 +	0000000   a 303  \n
   1.307 +	0000003
   1.308 +
   1.309 +	$ echo aä | ./cut -b -2 -n | od -c
   1.310 +	0000000   a  \n
   1.311 +	0000002
   1.312 +
   1.313 +Bei einer Implementierung, die -b und -c gleich behandelt,
   1.314 +ist die Ausgabe in allen drei Faellen wie die mittlere: Es
   1.315 +werden die ersten beiden Bytes ausgegeben.
   1.316 +
   1.317 +
   1.318 +
   1.319 +Implementierungen
   1.320 +
   1.321 +Nun zum Blick auf den Code. Hier soll eine Auswahl an
   1.322 +Implementierungen etwas genauer betrachtet werden. Fuer einen
   1.323 +ersten Eindruck ist der Umfang des Quellcodes hilfreich.
   1.324 +Typischerweise steigt dieser ueber die Jahre an. Diese
   1.325 +Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall,
   1.326 +bestaetigt werden.
   1.327 +
   1.328 +Die Unterstuetzung des Byte-Modus (-b) erfordert zwangslaeufig
   1.329 +mehr Code, deshalb ist zu erwarten, dass diejenigen
   1.330 +Implementierungen, die ihn haben, umfangreicher sind.
   1.331 +
   1.332 +Codevergleich
   1.333 +
   1.334 +SLOC	Zeilen	Bytes	Gehoert zu  	Dateidatum	Kategorie
   1.335 +-----------------------------------------------------------------
   1.336 +116	123	 2966	System III	1980-04-11	(trad)
   1.337 +118	125	 3038	4.3BSD-UWisc	1986-11-07	(trad)
   1.338 +200	256	 5715	4.3BSD-Reno	1990-06-25	(trad)
   1.339 +200	270	 6545	NetBSD	 	1993-03-21	(trad)
   1.340 +218	290	 6892	OpenBSD		2008-06-27	(pseudo)
   1.341 +224	296	 6920	FreeBSD		1994-05-27	(trad)
   1.342 +232	306	 7500	NetBSD 		2014-02-03	(pseudo)
   1.343 +340	405	 7423	Heirloom	2012-05-20	(POSIX)
   1.344 +382	586	14175	GNU coreutils	1992-11-08	(pseudo)
   1.345 +391	479	10961	FreeBSD		2012-11-24	(POSIX)
   1.346 +588	830	23167	GNU coreutils	2015-05-01	(pseudo)
   1.347 +
   1.348 +
   1.349 +$ awk -F'  +' '{printf("%d\t%d (%.2f)\t%d (%.2f)\t%s\t%s\t%s\n",
   1.350 +		$1, $2, $2/$1, $3, $3/$1, $4, $5, $6);}' <sloc                
   1.351 +116     123 (1.06)      2966 (25.57)    System III      1980-04-11   (trad)
   1.352 +118     125 (1.06)      3038 (25.75)    4.3BSD-UWisc    1986-11-07   (trad)
   1.353 +200     256 (1.28)      5715 (28.57)    4.3BSD-Reno     1990-06-25   (trad)
   1.354 +200     270 (1.35)      6545 (32.73)    NetBSD          1993-03-21   (trad)
   1.355 +218     290 (1.33)      6892 (31.61)    OpenBSD         2008-06-27   (pseudo)
   1.356 +224     296 (1.32)      6920 (30.89)    FreeBSD         1994-05-27   (trad)
   1.357 +232     306 (1.32)      7500 (32.33)    NetBSD          2014-02-03   (pseudo)
   1.358 +340     405 (1.19)      7423 (21.83)    Heirloom        2012-05-20   (POSIX)
   1.359 +382     586 (1.53)      14175 (37.11)   GNU coreutils   1992-11-08   (pseudo)
   1.360 +391     479 (1.23)      10961 (28.03)   FreeBSD         2012-11-24   (POSIX)
   1.361 +588     830 (1.41)      23167 (39.40)   GNU coreutils   2015-05-01   (pseudo)
   1.362 +
   1.363 +
   1.364 +Einige Auffaelligkeiten:
   1.365 +
   1.366 +Das Kandidatenfeld teilt sich grob in vier Gruppen: Die zwei urspruenglichen
   1.367 +Implementierungen, die sich nur minimal unterscheiden, mit gut 100 SLOCs.
   1.368 +Dann die fuenf BSD-Versionen mit knapp ueber 200 SLOCs. Anschliessend die
   1.369 +zwei POSIX-konformen Programme und die alte GNU-Version mit 350-400
   1.370 +SLOCs. Und zum Abschluss die moderne GNU-Variante mit fast 600 SLOCs.
   1.371 +
   1.372 +Die Abweichung von logischen Codezeilen (nach der Definition von
   1.373 +SLOCcount) und der Anzahl von Zeilenumbruechen in der Datei erstreckt 
   1.374 +sich ueber einen Faktor von 1.06 bei den aeltesten Vertretern bis zu
   1.375 +Faktor 1.5 bei GNU.
   1.376 +
   1.377 +Betrachtet man die Abweichungen zwischen den logischen Codezeilen und der
   1.378 +Dateigroesse, so pendelt das Teilnehmerfeld zwischen 25 und 30 Bytes je
   1.379 +Anweisung. Die Heirloom-Implementierung weicht nach unten ab, die
   1.380 +GNU-Implementierungen nach oben.
   1.381 +
   1.382 +
   1.383 +
   1.384 +Das cut in System III von 1980 ist, wie man anhand der SCCS-ID erkennen
   1.385 +kann bereits in Version 1.5. Die Vorversionen konnte ich aber leider nicht
   1.386 +ermitteln.
   1.387 +
   1.388 +Schaut man sich die SCCS-IDs in den BSD-Quellen an, dann findet man dort
   1.389 +Versionsnummern, die die Entwicklung dokumentieren:
   1.390 +
   1.391 +4.3bsd-uwisc	"@(#)cut.c      1.3";
   1.392 +4.3bsd-reno	"@(#)cut.c      5.3 (Berkeley) 6/24/90";
   1.393 +netbsd		"@(#)cut.c      5.4 (Berkeley) 10/30/90";
   1.394 +freebsd		"@(#)cut.c      8.1 (Berkeley) 6/6/93";
   1.395 +
   1.396 +Die neueren BSD-Versionen enthalten zwar weiterhin eine SCCS-ID, diese
   1.397 +ist aber bei Version "8.3 (Berkeley) 5/4/95" stehen geblieben. Danach
   1.398 +wurde scheinbar von SCCS auf CSV oder SVN gewechselt.
   1.399 +
   1.400 +Bei GNU befindet sich folgender Copyright-Vermerk im Code:
   1.401 +
   1.402 +   Copyright (C) 1997-2015 Free Software Foundation, Inc.
   1.403 +   Copyright (C) 1984 David M. Ihnat
   1.404 +
   1.405 +Wie aus weiteren Kommentaren zu entnehmen ist, wurde der Code von zuerst
   1.406 +von David MacKenzie und spaeter von Jim Meyering ueberarbeitet. Letzterer
   1.407 +hat den Code 1992 auch ins Versionkontrollsystem eingestellt. Weshalb
   1.408 +die Jahre zwischen 1992 und 1997 nicht im Copyright-Vermerk auftauchen,
   1.409 +ist unklar.
   1.410 +
   1.411 +
   1.412 +
   1.413 +
   1.414  Beschreibungen
   1.415  
   1.416  Interessant ist ein Vergleich der Kurzbeschreibungen von cut,
   1.417 @@ -202,6 +393,8 @@
   1.418  SunOS 4.1.3	remove selected fields from each line of a file
   1.419  SunOS 5.5.1	cut out selected fields of each line of a file
   1.420  
   1.421 +Heirloom Tools	cut out selected fields of each line of a file
   1.422 +
   1.423  POSIX		cut out selected fields of each line of a file
   1.424  
   1.425  GNU coreutils	remove sections from each line of files
   1.426 @@ -240,92 +433,6 @@
   1.427  
   1.428  
   1.429  
   1.430 -Codevergleich
   1.431 -
   1.432 -Nun zum Blick auf den Code. Hier soll eine Auswahl an
   1.433 -Implementierungen etwas genauer betrachtet werden. Fuer einen
   1.434 -ersten Eindruck ist der Umfang des Quellcodes hilfreich.
   1.435 -Typischerweise steigt dieser ueber die Jahre an. Diese
   1.436 -Beobachtung kann hier in der Tendenz aber nicht in jedem Fall
   1.437 -bestaetigt werden. Die Unterstuetzung des Byte-Modus (-b)
   1.438 -erfordert zwangslaeufig mehr Code, deshalb ist zu erwarten,
   1.439 -dass 
   1.440 -
   1.441 --b pseudo: openbsd, netbsd.2014, gnu*
   1.442 --b real: freebsd.2014
   1.443 -
   1.444 -:-& echo '123ä56' | cut -c -6 | od -c  
   1.445 -0000000   1   2   3 303 244   5  \n
   1.446 -0000007
   1.447 -
   1.448 -:-& echo '123ä56' | cut -b -6 | od -c
   1.449 -0000000   1   2   3 303 244   5  \n
   1.450 -0000007
   1.451 -
   1.452 -
   1.453 -$ wc -lc cut.c* | sort -n
   1.454 -  123  2966 cut.c__system_iii.1980-04-11
   1.455 -  125  3038 cut.c__4.3bsd-uwisc.1986-11-07
   1.456 -  256  5715 cut.c__4.3bsd-reno.1990-06-25
   1.457 -  270  6545 cut.c__netbsd.1993-03-21
   1.458 -  290  6892 cut.c__openbsd.2008-06-27	*
   1.459 -  296  6920 cut.c__freebsd.1994-05-27
   1.460 -  306  7500 cut.c__netbsd.2014-02-03	*
   1.461 -  479 10961 cut.c__freebsd.2012-11-24	*
   1.462 -  586 14175 cut.c__gnu.1992-11-08	*
   1.463 -  830 23167 cut.c__gnu.2015-05-01	*
   1.464 - 3271 80987 total
   1.465 -
   1.466 -$ c_count cut.c* | sort -n
   1.467 -Total:
   1.468 -116 cut.c__system_iii.1980-04-11
   1.469 -118 cut.c__4.3bsd-uwisc.1986-11-07
   1.470 -200 cut.c__4.3bsd-reno.1990-06-25
   1.471 -200 cut.c__netbsd.1993-03-21
   1.472 -218 cut.c__openbsd.2008-06-27	*
   1.473 -224 cut.c__freebsd.1994-05-27
   1.474 -232 cut.c__netbsd.2014-02-03	*
   1.475 -382 cut.c__gnu.1992-11-08	*
   1.476 -391 cut.c__freebsd.2012-11-24	*
   1.477 -588 cut.c__gnu.2015-05-01	*
   1.478 -2451
   1.479 -
   1.480 -(* == version hat -b)
   1.481 -
   1.482 -
   1.483 -
   1.484 -system_iii.1980-04-11	Release 1.5
   1.485 -
   1.486 -SCCSIDs:
   1.487 -
   1.488 -4.3bsd-uwisc.1986-11-07	"@(#)cut.c      1.3";
   1.489 -4.3bsd-reno.1990-06-25	"@(#)cut.c      5.3 (Berkeley) 6/24/90";
   1.490 -netbsd.1993-03-21	"@(#)cut.c      5.4 (Berkeley) 10/30/90";
   1.491 -freebsd.1994-05-27	"@(#)cut.c      8.1 (Berkeley) 6/6/93";
   1.492 -
   1.493 -freebsd.2012-11-24	"@(#)cut.c      8.3 (Berkeley) 5/4/95";
   1.494 -netbsd.2014-02-03	"@(#)cut.c      8.3 (Berkeley) 5/4/95";
   1.495 -
   1.496 -openbsd.2008-06-27	"@(#)cut.c      8.3 (Berkeley) 5/4/95";
   1.497 -			"$OpenBSD: cut.c,v 1.13 2008/06/27 08:02:13 sobrado Exp $";
   1.498 -
   1.499 -GNU
   1.500 -   Copyright (C) 1997-2015 Free Software Foundation, Inc.
   1.501 -   Copyright (C) 1984 David M. Ihnat
   1.502 -/* Written by David Ihnat.  */
   1.503 -
   1.504 -/* POSIX changes, bug fixes, long-named options, and cleanup
   1.505 -   by David MacKenzie <djm@gnu.ai.mit.edu>.
   1.506 -
   1.507 -   Rewrite cut_fields and cut_bytes -- Jim Meyering.  */
   1.508 -
   1.509 -1992-11-08
   1.510 -Jim Meyering
   1.511 -
   1.512 -
   1.513 -
   1.514 -
   1.515 -
   1.516  
   1.517  Autoreninfo
   1.518