docs/cut

annotate cut.de.ms @ 36:c584c7d907c5

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