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