docs/cut

annotate cut.txt @ 25:aea7a19d400f

Schlusspointe: So muss das verstanden werden!
author markus schnalke <meillo@marmaro.de>
date Mon, 29 Jun 2015 21:37:01 +0200
parents 7fd31331580a
children
rev   line source
meillo@6 1 cut - cut out selected fields of each line of a file
meillo@6 2 ----------------------------------------------------
meillo@6 3 markus schnalke <meillo@marmaro.de>
meillo@6 4 2015-05
meillo@0 5
meillo@0 6
meillo@1 7 Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
meillo@8 8 In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt
meillo@21 9 es, denn es ist ein schönes, praktisches und anschauliches
meillo@9 10 Helferlein. Hier soll ein wenig hinter seine Fassade geschaut
meillo@9 11 werden.
meillo@0 12
meillo@0 13
meillo@4 14 Funktionsweise
meillo@4 15
meillo@21 16 Ursprünglich hatte cut zwei Modi, die später um einen dritten
meillo@21 17 erweitert wurden. Cut schneidet entweder gewünschte Zeichen aus
meillo@21 18 den Zeilen der Eingabe oder gewünschte, durch Trennzeichen
meillo@8 19 definierte, Felder.
meillo@0 20
meillo@9 21 Der Zeichenmodus ist optimal geeignet um Festbreitenformate zu
meillo@19 22 zerteilen. Man kann damit beispielsweise bestimmte
meillo@9 23 Zugriffsrechte aus der Ausgabe von `ls -l' ausschneiden, in
meillo@9 24 diesem Beispiel die Rechte des Besitzers:
meillo@0 25
meillo@15 26 $ ls -l foo
meillo@15 27 -rw-rw-r-- 1 meillo users 0 May 12 07:32 foo
meillo@15 28
meillo@4 29 $ ls -l foo | cut -c 2-4
meillo@4 30 rw-
meillo@0 31
meillo@4 32 Oder die Schreibrechte des Besitzers, der Gruppe und der
meillo@4 33 Welt:
meillo@0 34
meillo@4 35 $ ls -l | cut -c 3,6,9
meillo@4 36 ww-
meillo@0 37
meillo@21 38 Mit cut lassen sich aber auch Strings kürzen.
meillo@0 39
meillo@10 40 $ long=12345678901234567890
meillo@10 41 $ echo "$long" | cut -c -10
meillo@10 42 1234567890
meillo@0 43
meillo@10 44 Dieser Befehl gibt die ersten maximal 10 Zeichen von
meillo@21 45 `$long' aus. (Alternativ kann man hierfür `printf
meillo@10 46 "%.10s\n" "$long"' verwenden.)
meillo@0 47
meillo@4 48 Geht es aber nicht um die Darstellung von Zeichen, sondern um
meillo@8 49 ihre Speicherung, dann ist `-c' nicht unbedingt geeignet.
meillo@21 50 Früher, als US-ASCII noch die omnipräsente Zeichenkodierung
meillo@17 51 war, wurde jedes Zeichen mit genau einem
meillo@21 52 Byte gespeichert. Somit selektierte `cut -c' gleichermaßen
meillo@4 53 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
meillo@4 54 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
meillo@21 55 dieser Annahme lösen. In diesem Zug bekam cut mit
meillo@9 56 POSIX.2-1992 einen Bytemodus (Option `-b'). Will man
meillo@4 57 also nur die ersten maximal 500 Bytes vor dem
meillo@0 58 Newline-Zeichen stehen haben (und den Rest stillschweigend
meillo@0 59 ignorieren), dann macht man das mit:
meillo@0 60
meillo@6 61 $ cut -b -500
meillo@0 62
meillo@4 63 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese
meillo@21 64 Funktion ist insbesondere für POSIX wichtig, da man damit
meillo@21 65 Textdateien mit begrenzter Zeilenlänge erzeugen kann.
meillo@4 66 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17
meillo@0 67
meillo@21 68 Wenn auch der Bytemodus neu eingeführt worden war, so sollte
meillo@17 69 er sich doch nur so verhalten wie der alte Zeichenmodus
meillo@17 70 normalerweise schon implementiert war. Beim Zeichenmodus aber
meillo@17 71 wurde eine neue Implementierungsweise gefordert. Das Problem
meillo@19 72 war folglich nicht, den neuen Bytemodus zu implementieren, sondern
meillo@10 73 den Zeichenmodus neu zu implementieren.
meillo@10 74
meillo@17 75 Neben dem Zeichen- und Bytemodus bietet cut noch den
meillo@17 76 Feldmodus, den man mit `-f' einleitet. Mit ihm
meillo@21 77 können Felder ausgewählt werden. Das Trennzeichen (per
meillo@21 78 Default der Tab) kann mit `-d' geändert werden. Es gilt in
meillo@21 79 gleicher Weise für die Eingabe und die Ausgabe.
meillo@0 80
meillo@21 81 Der typische Anwendungsfall für cut im Feldmodus ist die
meillo@19 82 Auswahl von Information aus der passwd-Datei. Hier z.B. der
meillo@17 83 Benutzername und seine ID:
meillo@0 84
meillo@17 85 $ cut -d: -f1,3 /etc/passwd
meillo@17 86 root:0
meillo@17 87 bin:1
meillo@17 88 daemon:2
meillo@17 89 mail:8
meillo@9 90 ...
meillo@0 91
meillo@21 92 (Die Argumente für die Optionen können bei cut übrigens
meillo@21 93 mit Whitespace abgetrennt oder direkt angehängt folgen.)
meillo@0 94
meillo@21 95 Dieser Feldmodus ist für einfache tabellarische Dateien,
meillo@4 96 wie eben die passwd, gut geeignet. Er kommt aber schnell an
meillo@21 97 seine Grenzen. Gerade der häufige Fall, dass an Whitespace
meillo@0 98 in Felder geteilt werden soll, wird damit nicht abgedeckt.
meillo@17 99 Der Delimiter kann bei cut nur genau ein Zeichen sein. Es kann
meillo@19 100 demnach nicht sowohl an Leerzeichen als auch an Tabs aufgetrennt
meillo@19 101 werden. Zudem unterteilt cut an jedem Trennzeichen. Zwei aneinander
meillo@21 102 stehende Trennzeichen führen zu einem leeren Feld. Dieses
meillo@8 103 Verhalten widerspricht den Erwartungen, die man an die
meillo@8 104 Verarbeitung einer Datei mit Whitespace-getrennten Feldern
meillo@8 105 hat. Manche Implementierungen von cut, z.B. die von FreeBSD,
meillo@21 106 haben deshalb Erweiterungen, die das gewünschte Verhalten
meillo@21 107 für Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn
meillo@9 108 man portabel bleiben will, verwendet man awk in diesen
meillo@21 109 Fällen.
meillo@0 110
meillo@4 111 Awk bietet noch eine weitere Funktion, die cut missen
meillo@21 112 lässt: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei
meillo@8 113 cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein
meillo@19 114 Feld kann selbst mehrfach angegeben werden. Dementsprechend gibt
meillo@19 115 der Aufruf
meillo@8 116 von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8
meillo@8 117 in genau dieser Reihenfolge aus. Die Auswahl entspricht damit
meillo@8 118 der Mengenlehre in der Mathematik: Jedes angegebene Feld wird
meillo@9 119 Teil der Ergebnismenge. Die Felder der Ergebnismenge sind
meillo@19 120 hierbei immer gleich geordnet wie in der Eingabe. Um die Worte
meillo@16 121 der Manpage von Version 8 Unix wiederzugeben: ``In data base
meillo@9 122 parlance, it projects a relation.''
meillo@16 123 [ http://man.cat-v.org/unix_8th/1/cut
meillo@21 124 Cut führt demnach die Datenbankoperation Projektion auf
meillo@21 125 Textdateien aus. Die Wikipedia erklärt das folgendermaßen:
meillo@7 126
meillo@7 127 Die Projektion entspricht der Projektionsabbildung aus der
meillo@7 128 Mengenlehre und kann auch Attributbeschränkung genannt
meillo@7 129 werden. Sie extrahiert einzelne Attribute aus der
meillo@7 130 ursprünglichen Attributmenge und ist somit als eine Art
meillo@7 131 Selektion auf Spaltenebene zu verstehen, das heißt, die
meillo@7 132 Projektion blendet Spalten aus.
meillo@7 133
meillo@8 134 [ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion
meillo@8 135
meillo@7 136
meillo@0 137 Geschichtliches
meillo@0 138
meillo@4 139 Cut erblickte 1982 mit dem Release von UNIX System III das
meillo@21 140 Licht der öffentlichen Welt. Wenn man die Quellen von System
meillo@22 141 III durchforstet, findet man cut.c mit dem Zeitstempel 1980-04-11.
meillo@1 142 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
meillo@22 143 Das ist die älteste Implementierung des Programms, die ich
meillo@21 144 aufstöbern konnte. Allerdings spricht die SCCS-ID im
meillo@22 145 Quellcode von Version 1.5. Die Vorgeschichte liegt, der Vermutung
meillo@20 146 Doug McIlroys
meillo@22 147 [ http://minnie.tuhs.org/pipermail/tuhs/2015-May/004083.html
meillo@22 148 zufolge, in PWB/UNIX, dessen Entwicklungslinie die Grundlage für
meillo@22 149 System III war. In den von PWB 1.0 (1977) verfügbaren Quellen
meillo@22 150 [ http://minnie.tuhs.org/Archive/PDP-11/Distributions/usdl/
meillo@23 151 ist cut noch nicht zu finden. Von PWB 2.0 scheinen keine
meillo@23 152 Quellen oder hilfreiche Dokumentation verfügbar zu sein.
meillo@22 153 PWB 3.0 wurde später aus Marketinggründen als System III
meillo@24 154 bezeichnet und ist folglich mit ihm identisch. Eine Nebenlinie zu
meillo@24 155 PWB war CB Unix, das nur innerhalb
meillo@22 156 der Bell Labs genutzt wurde. Das Handbuch von CB Unix Edition 2.1
meillo@24 157 vom November 1979 enthält die früheste Erwähnung von cut, die
meillo@24 158 meine Recherche zutage gefördert hat: eine Manpage für cut.
meillo@22 159 [ ftp://sunsite.icm.edu.pl/pub/unix/UnixArchive/PDP-11/Distributions/other/CB_Unix/cbunix_man1_02.pdf
meillo@0 160
meillo@24 161 Nun ein Blick auf die BSD-Linie: Dort ist der früheste
meillo@17 162 Fund ein cut.c mit dem Dateimodifikationsdatum 1986-11-07
meillo@8 163 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
meillo@8 164 als Teil der Spezialversion 4.3BSD-UWisc,
meillo@6 165 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
meillo@21 166 die im Januar 1987 veröffentlicht wurde.
meillo@8 167 Die Implementierung unterscheidet sich nur minimal von der
meillo@8 168 in System III.
meillo@17 169 Im bekannteren 4.3BSD-Tahoe (1988) tauchte cut nicht auf.
meillo@17 170 Das darauf folgende 4.3BSD-Reno (1990) lieferte aber wieder
meillo@17 171 ein cut mit aus. Dieses cut war ein von Adam S. Moskowitz und
meillo@8 172 Marciano Pitargue neu implementiertes cut, das 1989 in BSD
meillo@8 173 aufgenommen wurde.
meillo@1 174 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
meillo@4 175 Seine Manpage
meillo@1 176 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
meillo@21 177 erwähnt bereits die erwartete Konformität mit POSIX.2.
meillo@17 178 Nun muss man wissen, dass POSIX.2 erst im September
meillo@21 179 1992 veröffentlicht wurde, erst gut zwei Jahren nachdem die
meillo@17 180 Manpage und das Programm geschrieben worden waren. Das Programm
meillo@10 181 wurde folglich anhand von Arbeitsversionen des Standards
meillo@21 182 implementiert. Ein Blick in den Code bekräftigt diese Vermutung.
meillo@15 183 In der Funktion zum parsen der Feldauswahlliste findet sich
meillo@15 184 dieser Kommentar:
meillo@0 185
meillo@15 186 This parser is less restrictive than the Draft 9 POSIX spec.
meillo@15 187 POSIX doesn't allow lists that aren't in increasing order or
meillo@15 188 overlapping lists.
meillo@9 189
meillo@21 190 Im Draft 11.2 (1991-09) fordert POSIX diese Flexibilität bereits
meillo@15 191 ein:
meillo@12 192
meillo@15 193 The elements in list can be repeated, can overlap, and can
meillo@15 194 be specified in any order.
meillo@15 195
meillo@21 196 Zudem listet Draft 11.2 alle drei Modi, während in diesem
meillo@21 197 BSD cut nur die zwei alten implementiert sind. Es könnte also
meillo@17 198 sein, dass in Draft 9 der Bytemodus noch nicht vorhanden war.
meillo@23 199 Ohne Zugang zu Draft 9 oder 10, war es leider nicht möglich,
meillo@23 200 diese Vermutung zu prüfen.
meillo@17 201
meillo@21 202 Die Versionsnummern und Änderungsdaten der älteren
meillo@17 203 BSD-Implementierungen kann man aus den SCCS-IDs, die vom
meillo@21 204 damaligen Versionskontrollsystem in den Code eingefügt wurden,
meillo@15 205 ablesen. So z.B. bei 4.3BSD-Reno: ``5.3 (Berkeley) 6/24/90''.
meillo@12 206
meillo@21 207 Das cut der GNU Coreutils enthält folgenden Copyrightvermerk:
meillo@12 208
meillo@12 209 Copyright (C) 1997-2015 Free Software Foundation, Inc.
meillo@12 210 Copyright (C) 1984 David M. Ihnat
meillo@12 211
meillo@21 212 Der Code hat also recht alte Ursprünge. Wie aus weiteren
meillo@17 213 Kommentaren zu entnehmen ist, wurde der Programmcode zuerst von David
meillo@21 214 MacKenzie und später von Jim Meyering überarbeitet. Letzterer
meillo@12 215 hat den Code 1992 auch ins Versionkontrollsystem eingestellt.
meillo@17 216 Weshalb die Jahre vor 1997, zumindest ab 1992, nicht im
meillo@17 217 Copyright-Vermerk auftauchen, ist unklar.
meillo@12 218
meillo@21 219 Trotz der vielen Jahreszahlen aus den 80er Jahren gehört cut,
meillo@21 220 aus Sicht des ursprünglichen Unix, zu den jüngeren Tools.
meillo@21 221 Wenn cut auch ein Jahrzehnt älter als Linux, der Kernel, ist,
meillo@23 222 so war Unix schon über zehn Jahre alt, als cut das
meillo@21 223 erste Mal auftauchte. Insbesondere gehörte cut noch nicht
meillo@4 224 zu Version 7 Unix, das die Ausgangsbasis aller modernen
meillo@4 225 Unix-Systeme darstellt. Die weit komplexeren Programme sed
meillo@23 226 und awk waren dort aber schon vertreten. Man muss sich also
meillo@21 227 fragen, warum cut überhaupt noch entwickelt wurde, wo es
meillo@9 228 schon zwei Programme gab, die die Funktion von cut abdecken
meillo@21 229 konnten. Ein Argument für cut war sicher seine Kompaktheit und
meillo@21 230 die damit verbundene Geschwindigkeit gegenüber dem damals
meillo@21 231 trägen awk. Diese schlanke Gestalt ist es auch, die der
meillo@17 232 Unix-Philosopie entspricht: Mache eine Aufgabe und die richtig!
meillo@21 233 Cut überzeugte. Es wurde in andere Unix Varianten übernommen,
meillo@21 234 standardisiert und ist heutzutage überall anzutreffen.
meillo@1 235
meillo@21 236 Die ursprüngliche Variante (ohne -b) wurde schon 1985 in
meillo@5 237 der System V Interface Definition, einer wichtigen formalen
meillo@9 238 Beschreibung von UNIX System V, spezifiziert und tauchte
meillo@21 239 anschließend in allen relevanten Standards auf. Mit POSIX.2
meillo@9 240 im Jahre 1992 wurde cut zum ersten Mal in der heutigen Form
meillo@9 241 (mit -b) standardisiert.
meillo@1 242
meillo@1 243
meillo@21 244 Multibyte-Unterstützung
meillo@8 245
meillo@8 246 Nun sind der Bytemodus und die damit verbundene
meillo@8 247 Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit
meillo@8 248 1992 standardisiert, wie steht es aber mit deren Umsetzung?
meillo@10 249 Welche Versionen implementieren POSIX korrekt?
meillo@17 250 Die Situation ist dreiteilig: Es gibt historische
meillo@8 251 Implementierungen, die nur -c und -f kennen. Dann gibt es
meillo@10 252 Implementierungen die -b zwar kennen, es aber lediglich als Alias
meillo@21 253 für -c handhaben. Diese Implementierungen funktionieren mit
meillo@8 254 Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei
meillo@21 255 Multibyte-Encodings (z.B. UTF-8) verhält sich ihr -c aber
meillo@21 256 wie -b (und -n wird ignoriert). Schließlich gibt es noch
meillo@21 257 Implementierungen, die -b und -c tatsächlich POSIX-konform
meillo@8 258 implementieren.
meillo@8 259
meillo@17 260 Historische Zwei-Modi-Implementierungen sind z.B. die von
meillo@8 261 System III, System V und die aller BSDs bis in die 90er.
meillo@8 262
meillo@10 263 Pseudo-Multibyte-Implementierungen bieten GNU und die
meillo@17 264 modernen NetBSDs und OpenBSDs. Man darf sich sicher fragen,
meillo@21 265 ob dort ein Schein von POSIX-Konformität gewahrt wird.
meillo@15 266 Teilweise findet man erst nach genauerer Suche heraus, dass
meillo@15 267 -c und -n nicht wie erwartet funktionieren; teilweise machen es
meillo@17 268 sich die Systeme auch einfach, indem sie auf
meillo@23 269 Singlebyte-Zeichenkodierungen beharren, das aber dafür
meillo@17 270 klar darlegen:
meillo@8 271
meillo@15 272 Since we don't support multi-byte characters, the -c and -b
meillo@15 273 options are equivalent, and the -n option is meaningless.
meillo@8 274
meillo@16 275 [ http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/cut/cut.c?rev=1.18&content-type=text/x-cvsweb-markup
meillo@8 276
meillo@21 277 Tatsächlich standardkonforme Implementierungen, die
meillo@8 278 Multibytes korrekt handhaben, bekommt man bei einem modernen
meillo@8 279 FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins
meillo@9 280 im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert.
meillo@8 281 [ https://svnweb.freebsd.org/base?view=revision&revision=131194
meillo@21 282 Warum die beiden anderen großen BSDs diese Änderung nicht
meillo@21 283 übernommen haben, bleibt offen. Es scheint aber an der im
meillo@8 284 obigen Kommentar formulierten Grundausrichtung zu liegen.
meillo@8 285
meillo@23 286 Wie findet man nun als Nutzer heraus, ob beim cut des eigenen
meillo@21 287 Systems Multibytes korrekt unterstützt werden? Zuerst ist
meillo@8 288 entscheidend, ob das System selbst mit einem Multibyte-Encoding
meillo@17 289 arbeitet, denn tut es das nicht, dann entsprechen sich
meillo@21 290 Zeichen und Bytes und die Frage erübrigt sich. Man kann das
meillo@9 291 herausfinden indem man sich das Locale anschaut, aber einfacher
meillo@9 292 ist es, ein typisches Mehrbytezeichen, wie z.B. einen Umlaut,
meillo@9 293 auszugeben und zu schauen ob dieses in einem oder in mehreren
meillo@9 294 Bytes kodiert ist:
meillo@8 295
meillo@8 296 $ echo ä | od -c
meillo@8 297 0000000 303 244 \n
meillo@8 298 0000003
meillo@8 299
meillo@8 300 In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den
meillo@23 301 Zeilenumbruch fügt echo hinzu.)
meillo@8 302
meillo@23 303 Mit dem Programm iconv kann man Text explizit in bestimmte
meillo@10 304 Kodierungen konvertieren. Hier Beispiele, wie die Ausgabe
meillo@10 305 bei Latin1 und wie sie bei UTF-8 aussieht.
meillo@8 306
meillo@8 307 $ echo ä | iconv -t latin1 | od -c
meillo@8 308 0000000 344 \n
meillo@8 309 0000002
meillo@8 310
meillo@8 311 $ echo ä | iconv -t utf8 | od -c
meillo@8 312 0000000 303 244 \n
meillo@8 313 0000003
meillo@8 314
meillo@8 315 Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung)
meillo@8 316 wird recht sicher einer dieser beiden Ausgaben entsprechen.
meillo@8 317
meillo@8 318 Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System,
meillo@21 319 dann sollte sich eine POSIX-konforme Implementierung folgendermaßen
meillo@17 320 verhalten:
meillo@8 321
meillo@18 322 $ echo ä | cut -c 1 | od -c
meillo@10 323 0000000 303 244 \n
meillo@8 324 0000003
meillo@8 325
meillo@18 326 $ echo ä | cut -b 1 | od -c
meillo@10 327 0000000 303 \n
meillo@8 328 0000002
meillo@8 329
meillo@18 330 $ echo ä | cut -b 1 -n | od -c
meillo@10 331 0000000 \n
meillo@10 332 0000001
meillo@10 333
meillo@10 334 Bei einer Pseudo-POSIX-Implementierung ist die Ausgabe in
meillo@21 335 allen drei Fällen wie die mittlere: Es wird das erste Byte
meillo@10 336 ausgegeben.
meillo@8 337
meillo@8 338
meillo@8 339 Implementierungen
meillo@8 340
meillo@9 341 Nun ein Blick auf den Code. Betrachtet wird eine Auswahl an
meillo@9 342 Implementierungen.
meillo@9 343
meillo@21 344 Für einen ersten Eindruck ist der Umfang des Quellcodes
meillo@21 345 hilfreich. Typischerweise steigt dieser über die Jahre an. Diese
meillo@8 346 Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall,
meillo@21 347 bestätigt werden. Die POSIX-konforme Umsetzung des Zeichenmodus
meillo@21 348 erfordert zwangsläufig mehr Code, deshalb sind diese
meillo@17 349 Implementierungen tendenziell umfangreicher.
meillo@8 350
meillo@8 351
meillo@21 352 SLOC Zeilen Bytes Gehört zu Dateidatum Kategorie
meillo@9 353 -----------------------------------------------------------------
meillo@17 354 116 123 2966 System III 1980-04-11 (hist)
meillo@17 355 118 125 3038 4.3BSD-UWisc 1986-11-07 (hist)
meillo@17 356 200 256 5715 4.3BSD-Reno 1990-06-25 (hist)
meillo@17 357 200 270 6545 NetBSD 1993-03-21 (hist)
meillo@9 358 218 290 6892 OpenBSD 2008-06-27 (pseudo)
meillo@17 359 224 296 6920 FreeBSD 1994-05-27 (hist)
meillo@9 360 232 306 7500 NetBSD 2014-02-03 (pseudo)
meillo@9 361 340 405 7423 Heirloom 2012-05-20 (POSIX)
meillo@9 362 382 586 14175 GNU coreutils 1992-11-08 (pseudo)
meillo@9 363 391 479 10961 FreeBSD 2012-11-24 (POSIX)
meillo@9 364 588 830 23167 GNU coreutils 2015-05-01 (pseudo)
meillo@8 365
meillo@8 366
meillo@9 367 Das Kandidatenfeld teilt sich grob in vier Gruppen: (1) Die zwei
meillo@21 368 ursprünglichen Implementierungen, die sich nur minimal
meillo@21 369 unterscheiden, mit gut 100 SLOCs. (2) Die fünf BSD-Versionen mit
meillo@9 370 gut 200 SLOCs. (3) Die zwei POSIX-konformen Programme und
meillo@21 371 die alte GNU-Version mit 340-390 SLOCs. Und schließlich (4) die
meillo@17 372 moderne GNU-Variante mit fast 600 SLOCs.
meillo@8 373
meillo@9 374 Die Abweichung zwischen logischen Codezeilen (SLOC, ermittelt mit
meillo@21 375 SLOCcount) und der Anzahl von Zeilenumbrüchen in der Datei (`wc
meillo@21 376 -l') erstreckt sich über eine Spanne von Faktor 1.06 bei den
meillo@21 377 ältesten Vertretern bis zu Faktor 1.5 bei GNU. Den größten
meillo@19 378 Einfluss darauf haben Leerzeilen, reine Kommentarzeilen und
meillo@21 379 die Größe des Lizenzblocks am Dateianfang.
meillo@8 380
meillo@9 381 Betrachtet man die Abweichungen zwischen den logischen Codezeilen
meillo@21 382 und der Dateigröße (`wc -c'), so pendelt das Teilnehmerfeld
meillo@9 383 zwischen 25 und 30 Bytes je Anweisung. Die Heirloom-Implementierung
meillo@9 384 weicht mit nur 21 nach unten ab, die GNU-Implementierungen mit
meillo@21 385 fast 40 nach oben. Bei GNU liegt dies hauptsächlich an deren
meillo@21 386 Programmierstil, mit spezieller Einrückung und langen Bezeichnern.
meillo@21 387 Ob man die Heirloom-Implementierung
meillo@22 388 [ http://heirloom.cvs.sourceforge.net/viewvc/heirloom/heirloom/cut/cut.c?revision=1.6&view=markup
meillo@21 389 als besonders kryptisch
meillo@9 390 oder als besonders elegant bezeichnen will, das soll der
meillo@21 391 eigenen Einschätzung des Lesers überlassen bleiben. Vor allem
meillo@21 392 der Vergleich mit einer GNU-Implementierung
meillo@22 393 [ http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=blob;f=src/cut.c;hb=e981643
meillo@21 394 ist eindrucksvoll.
meillo@8 395
meillo@8 396
meillo@21 397 Die interne Struktur der Programmcodes (in C) ist meist ähnlich.
meillo@17 398 Neben der obligatorischen main-Funktion, die die Kommandozeilenargumente
meillo@11 399 verarbeitet, gibt es im Normalfall eine Funktion, die die
meillo@21 400 Feldauswahl in eine interne Datenstruktur überführt. Desweiteren
meillo@23 401 haben fast alle Implementierungen separate Funktionen für jeden
meillo@23 402 ihrer Modi. Bei den POSIX-konformen Implementierungen
meillo@11 403 wird die `-b -n'-Kombination als weiterer Modus behandelt, und
meillo@21 404 damit in einer eigenen Funktion umgesetzt. Nur bei der frühen
meillo@11 405 System III-Implementierung (und seiner 4.3BSD-UWisc-Variante)
meillo@21 406 wird außer den Fehlerausgaben alles in der main-Funktion
meillo@17 407 erledigt.
meillo@11 408
meillo@15 409 Cut-Implementierungen haben typischerweise zwei limitierende
meillo@21 410 Größen: Die Maximalanzahl unterstützter Felder und die maximale
meillo@21 411 Zeilenlänge. Bei System III sind beide Größen auf 512 begrenzt.
meillo@17 412 4.3BSD-Reno und die BSDs der 90er Jahre haben ebenfalls fixe
meillo@17 413 Grenzen (_BSD_LINE_MAX bzw. _POSIX2_LINE_MAX). Bei modernen
meillo@17 414 FreeBSDs, NetBSDs, bei allen GNU-Implementierungen und bei
meillo@17 415 Heirloom kann sowohl die Felderanzahl als auch die maximale
meillo@21 416 Zeilenlänge beliebig groß werden; der Speicher dafür wird
meillo@17 417 dynamisch alloziiert. OpenBSD ist ein Hybrid aus fixer
meillo@21 418 Maximalzahl an Feldern, aber beliebiger Zeilenlänge. Die
meillo@17 419 begrenzte Felderanzahl scheint jedoch kein Praxisproblem
meillo@17 420 darzustellen, da _POSIX2_LINE_MAX mit mindestens 2048 durchaus
meillo@21 421 groß genug sein sollte.
meillo@11 422
meillo@8 423
meillo@2 424 Beschreibungen
meillo@1 425
meillo@19 426 Interessant ist zudem ein Vergleich der Kurzbeschreibungen von
meillo@17 427 cut, wie sie sich in der Titelzeile der Manpages oder manchmal
meillo@19 428 am Anfang der Quellcodedatei finden. Die folgende Liste
meillo@9 429 ist grob zeitlich geordnet und nach Abstammung gruppiert:
meillo@3 430
meillo@3 431
meillo@22 432 CB Unix cut out selected fields of each line of a file
meillo@2 433 System III cut out selected fields of each line of a file
meillo@3 434 System III (src) cut and paste columns of a table (projection of a relation)
meillo@2 435 System V cut out selected fields of each line of a file
meillo@2 436 HP-UX cut out (extract) selected fields of each line of a file
meillo@2 437
meillo@3 438 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
meillo@2 439 4.3BSD-Reno select portions of each line of a file
meillo@2 440 NetBSD select portions of each line of a file
meillo@7 441 OpenBSD 4.6 select portions of each line of a file
meillo@2 442 FreeBSD 1.0 select portions of each line of a file
meillo@10 443 FreeBSD 10.0 cut out selected portions of each line of a file
meillo@2 444 SunOS 4.1.3 remove selected fields from each line of a file
meillo@2 445 SunOS 5.5.1 cut out selected fields of each line of a file
meillo@2 446
meillo@8 447 Heirloom Tools cut out selected fields of each line of a file
meillo@9 448 Heirloom Tools (src) cut out fields of lines of files
meillo@2 449
meillo@2 450 GNU coreutils remove sections from each line of files
meillo@2 451
meillo@2 452 Minix select out columns of a file
meillo@2 453
meillo@2 454 Version 8 Unix rearrange columns of data
meillo@2 455 ``Unix Reader'' rearrange columns of text
meillo@2 456
meillo@9 457 POSIX cut out selected fields of each line of a file
meillo@2 458
meillo@9 459
meillo@9 460 Die mit ``(src)'' markierten Beschreibungen sind aus dem
meillo@21 461 jeweiligen Quellcode entnommen. Der POSIX-Eintrag enthält
meillo@18 462 die Beschreibung im Standard. Der ``Unix Reader'' ist ein
meillo@21 463 rückblickendes Textdokument von Doug McIlroy, das das
meillo@18 464 Auftreten der Tools in der Geschichte des Research Unix zum
meillo@17 465 Thema hat.
meillo@16 466 [ http://doc.cat-v.org/unix/unix-reader/contents.pdf
meillo@17 467 Eigentlich sollte seine Beschreibung der in Version 8 Unix
meillo@21 468 entsprechen. Die Abweichung könnte ein Übertragungsfehler
meillo@21 469 oder eine nachträgliche Korrektur sein. Alle übrigen
meillo@19 470 Beschreibungen entstammen den Manpages.
meillo@5 471
meillo@21 472 Oft ist mit der Zeit die POSIX-Beschreibung übernommen
meillo@17 473 oder an sie angeglichen worden, wie beispielsweise bei FreeBSD.
meillo@5 474 [ https://svnweb.freebsd.org/base?view=revision&revision=167101
meillo@5 475
meillo@7 476 Interessant ist, dass die GNU coreutils seit Anbeginn vom
meillo@5 477 Entfernen von Teilen der Eingabe sprechen, wohingegen die
meillo@21 478 Kommandozeilenangabe klar ein Auswählen darstellt. Die
meillo@21 479 Worte ``cut out'' sind vielleicht auch zu missverständlich.
meillo@21 480 HP-UX hat sie deshalb präzisiert.
meillo@5 481
meillo@19 482 Beim Begriff, was selektiert wird, ist man sich ebenfalls
meillo@17 483 uneins. Die Einen reden von Feldern (POSIX), Andere von
meillo@17 484 Abschnitten bzw. Teilen (BSD) und wieder Andere von Spalten
meillo@25 485 (Research Unix). Die scheinbar unzutreffende Beschreibung
meillo@25 486 bei Version 8 Unix (``rearrange columns of data'') ist
meillo@25 487 dadurch zu erklären, dass die Manpage sowohl cut als auch
meillo@25 488 paste abdeckt. In ihrer Kombination können tatsächlich
meillo@25 489 Spalten umgeordnet werden.
meillo@5 490
meillo@5 491
meillo@6 492 Autoreninfo
meillo@6 493
meillo@21 494 Markus Schnalke interessiert sich für die Hintergründe
meillo@21 495 von Unix und seinen Werkzeugen. Für die Erarbeitung dieses
meillo@6 496 Textes wurde er regelrecht zum Historiker.
meillo@6 497
meillo@6 498
meillo@6 499 Lizenz
meillo@10 500
meillo@6 501 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported
meillo@21 502 veröffentlicht werden)