Mercurial > docs > cut
annotate cut.txt @ 15:77d1f55bba08
Weitere Ueberarbeitungen
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 12 May 2015 07:35:33 +0200 |
parents | bf5e41260f89 |
children | 4d8196c836d8 |
rev | line source |
---|---|
6 | 1 cut - cut out selected fields of each line of a file |
2 ---------------------------------------------------- | |
3 markus schnalke <meillo@marmaro.de> | |
4 2015-05 | |
0 | 5 |
6 | |
1 | 7 Cut ist ein klassisches Programm im Unix-Werkzeugkasten. |
8 | 8 In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt |
9 | 9 es, denn es ist ein schoenes, praktisches und anschauliches |
10 Helferlein. Hier soll ein wenig hinter seine Fassade geschaut | |
11 werden. | |
0 | 12 |
13 | |
4 | 14 Funktionsweise |
15 | |
8 | 16 Urspruenglich hatte cut zwei Modi, die spaeter um einen dritten |
9 | 17 erweitert wurden. Cut schneidet entweder gewuenschte Zeichen aus |
18 den Zeilen der Eingabe oder gewuenschte, durch Trennzeichen | |
8 | 19 definierte, Felder. |
0 | 20 |
9 | 21 Der Zeichenmodus ist optimal geeignet um Festbreitenformate zu |
8 | 22 zerteilen. So kann man damit beispielsweise bestimmte |
9 | 23 Zugriffsrechte aus der Ausgabe von `ls -l' ausschneiden, in |
24 diesem Beispiel die Rechte des Besitzers: | |
0 | 25 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
26 $ ls -l foo |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
27 -rw-rw-r-- 1 meillo users 0 May 12 07:32 foo |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
28 |
4 | 29 $ ls -l foo | cut -c 2-4 |
30 rw- | |
0 | 31 |
4 | 32 Oder die Schreibrechte des Besitzers, der Gruppe und der |
33 Welt: | |
0 | 34 |
4 | 35 $ ls -l | cut -c 3,6,9 |
36 ww- | |
0 | 37 |
4 | 38 Mit cut lassen sich aber auch Strings kuerzen. |
0 | 39 |
10 | 40 $ long=12345678901234567890 |
41 $ echo "$long" | cut -c -10 | |
42 1234567890 | |
0 | 43 |
10 | 44 Dieser Befehl gibt die ersten maximal 10 Zeichen von |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
45 `$long' aus. (Alternativ kann man hierfuer `printf |
10 | 46 "%.10s\n" "$long"' verwenden.) |
0 | 47 |
4 | 48 Geht es aber nicht um die Darstellung von Zeichen, sondern um |
8 | 49 ihre Speicherung, dann ist `-c' nicht unbedingt geeignet. |
50 Frueher, als US-ASCII als Zeichensatz und -kodierung | |
4 | 51 noch omnipraesent war, wurde jedes Zeichen mit genau einem |
52 Byte gespeichert. Somit selektierte `cut -c' gleichermassen | |
53 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von | |
54 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von | |
55 dieser Annahme loesen. In diesem Zug bekam cut mit | |
9 | 56 POSIX.2-1992 einen Bytemodus (Option `-b'). Will man |
4 | 57 also nur die ersten maximal 500 Bytes vor dem |
0 | 58 Newline-Zeichen stehen haben (und den Rest stillschweigend |
59 ignorieren), dann macht man das mit: | |
60 | |
6 | 61 $ cut -b -500 |
0 | 62 |
4 | 63 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese |
8 | 64 Funktion ist insbesondere fuer POSIX wichtig, da man so |
65 Textdateien mit begrenzter Zeilenlaenge erzeugen kann. | |
4 | 66 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17 |
0 | 67 |
10 | 68 Auch wenn der Bytemodus neu eingefuehrt wurde, so sollte er |
69 sich doch nur so verhalten wie der alte Zeichenmodus normalerweise | |
70 implementiert war. Beim Zeichenmodus aber wurde durch POSIX.2 | |
71 eine andere Implementierungsweise gefordert. Das Problem war | |
72 also nicht, den neuen Bytemodus zu implementieren, sondern | |
73 den Zeichenmodus neu zu implementieren. | |
74 | |
75 Neben dem Zeichen- und Byte-Modus bietet cut noch den | |
8 | 76 Feld-Modus, den man mit `-f' einleitet. Mit ihm |
4 | 77 koennen Felder ausgewaehlt werden. Das Trennzeichen (per |
78 Default der Tab) kann mit `-d' geaendert werden. | |
0 | 79 |
8 | 80 Der typische Anwendungsfall fuer cut im Feld-Modus ist die |
81 Auswahl von Information aus der passwd-Datei. So z.B. der | |
10 | 82 Benutzername, seine ID und das Homeverzeichnis: |
0 | 83 |
6 | 84 $ cut -d: -f1,3,6 /etc/passwd |
9 | 85 root:0:/root |
86 bin:1:/bin | |
87 daemon:2:/sbin | |
88 mail:8:/var/spool/mail | |
89 ... | |
0 | 90 |
91 (Die Argumente fuer die Optionen koennen bei cut uebrigens | |
8 | 92 mit Whitespace abgetrennt oder direkt angehaengt folgen.) |
0 | 93 |
4 | 94 Dieser Feld-Modus ist fuer einfache tabellarische Dateien, |
95 wie eben die passwd, gut geeignet. Er kommt aber schnell an | |
9 | 96 seine Grenzen. Gerade der haeufige Fall, dass an Whitespace |
0 | 97 in Felder geteilt werden soll, wird damit nicht abgedeckt. |
98 Der Delimiter kann nur genau ein Zeichen sein. Es kann also | |
99 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden. | |
100 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander | |
4 | 101 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses |
8 | 102 Verhalten widerspricht den Erwartungen, die man an die |
103 Verarbeitung einer Datei mit Whitespace-getrennten Feldern | |
104 hat. Manche Implementierungen von cut, z.B. die von FreeBSD, | |
9 | 105 haben aber Erweiterungen, die das gewuenschte Verhalten fuer |
8 | 106 Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn |
9 | 107 man portabel bleiben will, verwendet man awk in diesen |
108 Faellen. | |
0 | 109 |
4 | 110 Awk bietet noch eine weitere Funktion, die cut missen |
8 | 111 laesst: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei |
112 cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein | |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
113 Feld kann selbst mehrfach angegeben werden. So gibt der Aufruf |
8 | 114 von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8 |
115 in genau dieser Reihenfolge aus. Die Auswahl entspricht damit | |
116 der Mengenlehre in der Mathematik: Jedes angegebene Feld wird | |
9 | 117 Teil der Ergebnismenge. Die Felder der Ergebnismenge sind |
118 dabei immer gleich geordnet wie in der Eingabe. Um die Worte | |
119 der Manpage XXX von Version 8 Unix wiederzugeben: ``In data base | |
120 parlance, it projects a relation.'' | |
121 [ XXX | |
8 | 122 Cut fuehrt also die Datenbankoperation Projektion auf |
10 | 123 Textdateien aus. Die Wikipedia erklaert das folgendermassen: |
7 | 124 |
125 Die Projektion entspricht der Projektionsabbildung aus der | |
126 Mengenlehre und kann auch Attributbeschränkung genannt | |
127 werden. Sie extrahiert einzelne Attribute aus der | |
128 ursprünglichen Attributmenge und ist somit als eine Art | |
129 Selektion auf Spaltenebene zu verstehen, das heißt, die | |
130 Projektion blendet Spalten aus. | |
131 | |
8 | 132 [ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion |
133 | |
7 | 134 |
0 | 135 Geschichtliches |
136 | |
4 | 137 Cut erblickte 1982 mit dem Release von UNIX System III das |
138 Licht der oeffentlichen Welt. Wenn man die Quellen von System | |
139 III durchforstet, findet man die Quellcodedatei cut.c mit dem | |
140 Zeitstempel 1980-04-11. | |
1 | 141 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd |
4 | 142 Das ist die aelteste Manifestation des Programms, die ich |
8 | 143 aufstoebern konnte. Allerdings spricht die sccsid im |
144 Quellcode von Version 1.5. Es muss also noch eine | |
145 Vorgeschichte geben. Zu dieser habe ich leider keinen Zugang | |
146 gefunden. | |
9 | 147 XXX mail an TUHS |
0 | 148 |
10 | 149 Nun ein Blick auf die BSD-Linie: Dort ist mein |
8 | 150 fruehester Fund ein cut.c mit dem Dateimodifikationsdatum |
151 1986-11-07 | |
152 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut | |
153 als Teil der Spezialversion 4.3BSD-UWisc, | |
6 | 154 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix |
155 die im Januar 1987 veroeffentlicht wurde. | |
8 | 156 Die Implementierung unterscheidet sich nur minimal von der |
157 in System III. | |
158 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut nicht auf. | |
159 Das darauf folgende 4.3BSD-Reno (1990) liefert aber wieder | |
160 ein cut mit aus. Dieses cut ist ein von Adam S. Moskowitz und | |
161 Marciano Pitargue neu implementiertes cut, das 1989 in BSD | |
162 aufgenommen wurde. | |
1 | 163 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut |
4 | 164 Seine Manpage |
1 | 165 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1 |
4 | 166 erwaehnt bereits die erwartete Konformitaet mit POSIX.2. |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
167 XXX 2 oder 3 modi? Draft 9: 2 modi? Draft 11.2 hat 3 modi! |
4 | 168 Nun sollte man wissen, dass POSIX.2 erst im September |
10 | 169 1992 veroeffentlicht wurde, also gut zwei Jahren nachdem die |
8 | 170 Manpage und das Programm geschrieben wurden. Das Programm |
10 | 171 wurde folglich anhand von Arbeitsversionen des Standards |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
172 implementiert. Ein Blick in den Code bekraeftigt diese Vermutung. |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
173 In der Funktion zum parsen der Feldauswahlliste findet sich |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
174 dieser Kommentar: |
0 | 175 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
176 This parser is less restrictive than the Draft 9 POSIX spec. |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
177 POSIX doesn't allow lists that aren't in increasing order or |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
178 overlapping lists. |
12 | 179 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
180 Im Draft 11.2 (1991-09) fordert POSIX diese Flexibilitaet bereits |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
181 ein: |
9 | 182 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
183 The elements in list can be repeated, can overlap, and can |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
184 be specified in any order. |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
185 |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
186 Die Versionsnummern und Aenderungsdatums der aelteren |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
187 BSD-Implementierungen kann man aus den SCCS-IDs (die vom |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
188 damaligen Versionskontrollsystem in den Code eingefuegt wurden) |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
189 ablesen. So z.B. bei 4.3BSD-Reno: ``5.3 (Berkeley) 6/24/90''. |
12 | 190 |
191 Das cut der GNU Coreutils enthaelt folgenden Copyrightvermerk: | |
192 | |
193 Copyright (C) 1997-2015 Free Software Foundation, Inc. | |
194 Copyright (C) 1984 David M. Ihnat | |
195 | |
196 Der Code hat also ziemlich alte Urspruenge. Wie aus weiteren | |
197 Kommentaren zu entnehmen ist, wurde der Code zuerst von David | |
198 MacKenzie und spaeter von Jim Meyering ueberarbeitet. Letzterer | |
199 hat den Code 1992 auch ins Versionkontrollsystem eingestellt. | |
200 Weshalb die Jahre zwischen 1992 und 1997 nicht im Copyright-Vermerk | |
201 auftauchen, ist unklar. | |
202 | |
203 Trotz der vielen Jahreszahlen aus den 80er Jahren gehoert cut, | |
10 | 204 aus Sicht des urspruenglichen Unix, zu den juengeren Tools. |
1 | 205 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist, |
4 | 206 so war Unix doch schon ueber zehn Jahre alt, als cut das |
9 | 207 erste Mal auftauchte. Insbesondere gehoerte cut auch noch nicht |
4 | 208 zu Version 7 Unix, das die Ausgangsbasis aller modernen |
209 Unix-Systeme darstellt. Die weit komplexeren Programme sed | |
210 und awk waren dort schon vertreten. Man muss sich also | |
211 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es | |
9 | 212 schon zwei Programme gab, die die Funktion von cut abdecken |
213 konnten. Ein Argument fuer cut war sicher seine Kompaktheit und | |
4 | 214 die damit verbundene Geschwindigkeit gegenueber dem damals |
215 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix | |
216 Philosopie entspricht: Mache eine Aufgabe und die richtig! | |
9 | 217 Cut ueberzeugte. Es wurde in andere Unix Varianten uebernommen, |
218 standardisiert und ist heutzutage ueberall anzutreffen. | |
1 | 219 |
9 | 220 Die urspruengliche Variante (ohne -b) wurde schon 1985 in |
5 | 221 der System V Interface Definition, einer wichtigen formalen |
9 | 222 Beschreibung von UNIX System V, spezifiziert und tauchte |
223 anschliessend in allen relevanten Standards auf. Mit POSIX.2 | |
224 im Jahre 1992 wurde cut zum ersten Mal in der heutigen Form | |
225 (mit -b) standardisiert. | |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
226 XXX sicher? |
2 | 227 |
228 | |
9 | 229 Multibyte-Unterstuetzung |
8 | 230 |
231 Nun sind der Bytemodus und die damit verbundene | |
232 Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit | |
233 1992 standardisiert, wie steht es aber mit deren Umsetzung? | |
10 | 234 Welche Versionen implementieren POSIX korrekt? |
9 | 235 Die Situation ist dreiteilig: Es gibt traditionelle |
8 | 236 Implementierungen, die nur -c und -f kennen. Dann gibt es |
10 | 237 Implementierungen die -b zwar kennen, es aber lediglich als Alias |
8 | 238 fuer -c handhaben. Diese Implementierungen funktionieren mit |
239 Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei | |
240 Multi-Byte-Encodings (z.B. UTF-8) verhaelt sich ihr -c aber | |
241 wie -b (und -n wird ignoriert). Schliesslich gibt es noch | |
242 Implementierungen, die -b und -c tatsaechlich POSIX-konform | |
243 implementieren. | |
244 | |
245 Traditionelle Zwei-Modi-Implementierungen sind z.B. die von | |
246 System III, System V und die aller BSDs bis in die 90er. | |
247 | |
10 | 248 Pseudo-Multibyte-Implementierungen bieten GNU und die |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
249 modernen NetBSDs und OpenBSDs. Man darf sich durchaus fragen, |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
250 ob dort ein Schein von POSIX-Konformitaet gewahrt wird. |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
251 Teilweise findet man erst nach genauerer Suche heraus, dass |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
252 -c und -n nicht wie erwartet funktionieren; teilweise machen es |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
253 sich die System auch einfach, indem sie auf |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
254 Singlebyte-Zeichenkodierungen beharren, das aber dafuer klar |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
255 darlegen: |
8 | 256 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
257 Since we don't support multi-byte characters, the -c and -b |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
258 options are equivalent, and the -n option is meaningless. |
8 | 259 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
260 [ openbsd XXX |
8 | 261 |
262 Tatsaechlich standardkonforme Implementierungen, die | |
263 Multibytes korrekt handhaben, bekommt man bei einem modernen | |
264 FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins | |
9 | 265 im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert. |
8 | 266 [ https://svnweb.freebsd.org/base?view=revision&revision=131194 |
267 Warum die beiden anderen grossen BSDs diese Aenderung nicht | |
268 uebernommen haben, bleibt offen. Es scheint aber an der im | |
269 obigen Kommentar formulierten Grundausrichtung zu liegen. | |
270 | |
271 Wie findet man als Nutzer heraus, ob beim cut(1) des eigenen | |
272 Systems Multibytes korrekt unterstuetzt werden? Zuerst ist | |
273 entscheidend, ob das System selbst mit einem Multibyte-Encoding | |
9 | 274 arbeitet, denn tut es das nicht, dann entsprechen sich naemlich |
275 Zeichen und Bytes und die Frage eruebrigt sich. Man kann das | |
276 herausfinden indem man sich das Locale anschaut, aber einfacher | |
277 ist es, ein typisches Mehrbytezeichen, wie z.B. einen Umlaut, | |
278 auszugeben und zu schauen ob dieses in einem oder in mehreren | |
279 Bytes kodiert ist: | |
8 | 280 |
281 $ echo ä | od -c | |
282 0000000 303 244 \n | |
283 0000003 | |
284 | |
285 In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den | |
286 Zeilenumbruch fuegt echo(1) hinzu.) | |
287 | |
9 | 288 Mit dem Programm iconv(1) kann man Text explizit in bestimmte |
10 | 289 Kodierungen konvertieren. Hier Beispiele, wie die Ausgabe |
290 bei Latin1 und wie sie bei UTF-8 aussieht. | |
8 | 291 |
292 $ echo ä | iconv -t latin1 | od -c | |
293 0000000 344 \n | |
294 0000002 | |
295 | |
296 $ echo ä | iconv -t utf8 | od -c | |
297 0000000 303 244 \n | |
298 0000003 | |
299 | |
300 Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung) | |
301 wird recht sicher einer dieser beiden Ausgaben entsprechen. | |
302 | |
303 Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System, | |
304 dann sollte sich eine POSIX-konforme Implementierung so verhalten: | |
305 | |
10 | 306 $ echo ä | ./cut -c 1 | od -c |
307 0000000 303 244 \n | |
8 | 308 0000003 |
309 | |
10 | 310 $ echo ä | ./cut -b 1 | od -c |
311 0000000 303 \n | |
8 | 312 0000002 |
313 | |
10 | 314 $ echo ä | ./cut -b 1 -n | od -c |
315 0000000 \n | |
316 0000001 | |
317 | |
318 Bei einer Pseudo-POSIX-Implementierung ist die Ausgabe in | |
319 allen drei Faellen wie die mittlere: Es wird das erste Byte | |
320 ausgegeben. | |
8 | 321 |
322 | |
323 Implementierungen | |
324 | |
9 | 325 Nun ein Blick auf den Code. Betrachtet wird eine Auswahl an |
326 Implementierungen. | |
327 | |
328 Fuer einen ersten Eindruck ist der Umfang des Quellcodes | |
329 hilfreich. Typischerweise steigt dieser ueber die Jahre an. Diese | |
8 | 330 Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall, |
9 | 331 bestaetigt werden. Die Unterstuetzung des Byte-Modus (-b) |
332 erfordert zwangslaeufig mehr Code, deshalb sind die | |
333 POSIX-konformen Implementierungen tendenziell umfangreicher. | |
8 | 334 |
335 | |
9 | 336 SLOC Zeilen Bytes Gehoert zu Dateidatum Kategorie |
337 ----------------------------------------------------------------- | |
338 116 123 2966 System III 1980-04-11 (trad) | |
339 118 125 3038 4.3BSD-UWisc 1986-11-07 (trad) | |
340 200 256 5715 4.3BSD-Reno 1990-06-25 (trad) | |
341 200 270 6545 NetBSD 1993-03-21 (trad) | |
342 218 290 6892 OpenBSD 2008-06-27 (pseudo) | |
343 224 296 6920 FreeBSD 1994-05-27 (trad) | |
344 232 306 7500 NetBSD 2014-02-03 (pseudo) | |
345 340 405 7423 Heirloom 2012-05-20 (POSIX) | |
346 382 586 14175 GNU coreutils 1992-11-08 (pseudo) | |
347 391 479 10961 FreeBSD 2012-11-24 (POSIX) | |
348 588 830 23167 GNU coreutils 2015-05-01 (pseudo) | |
349 XXX verlinken | |
8 | 350 |
351 | |
9 | 352 Das Kandidatenfeld teilt sich grob in vier Gruppen: (1) Die zwei |
353 urspruenglichen Implementierungen, die sich nur minimal | |
354 unterscheiden, mit gut 100 SLOCs. (2) Die fuenf BSD-Versionen mit | |
355 gut 200 SLOCs. (3) Die zwei POSIX-konformen Programme und | |
356 die alte GNU-Version mit 340-390 SLOCs. Und (4) die moderne | |
357 GNU-Variante mit fast 600 SLOCs. | |
358 | |
359 Die Abweichung zwischen logischen Codezeilen (SLOC, ermittelt mit | |
360 SLOCcount) und der Anzahl von Zeilenumbruechen in der Datei (`wc | |
361 -l') erstreckt sich ueber einen Faktor von 1.06 bei den aeltesten | |
362 Vertretern bis zu Faktor 1.5 bei GNU. Der groesste | |
363 Einflussfaktor darauf sind Leerzeilen, reine Kommentarzeilen und | |
364 die Groesse des Lizenzblocks am Dateianfang. | |
365 | |
366 Betrachtet man die Abweichungen zwischen den logischen Codezeilen | |
367 und der Dateigroesse (`wc -c'), so pendelt das Teilnehmerfeld | |
368 zwischen 25 und 30 Bytes je Anweisung. Die Heirloom-Implementierung | |
369 weicht mit nur 21 nach unten ab, die GNU-Implementierungen mit | |
10 | 370 fast 40 nach oben. Dies liegt bei GNU hauptsaechlich an deren |
9 | 371 Programmierstil, mit spezieller Einrueckung und langen Bezeichnern. |
372 Ob man die Heirloom-Implementierung als besonders kryptisch | |
373 oder als besonders elegant bezeichnen will, das soll der | |
374 eigenen Einschaetzung des Lesers ueberlassen bleiben. | |
8 | 375 |
376 | |
11 | 377 Die interne Struktur des C-Codes ist meist aehnlich. Neben der |
378 obligatorischen main-Funktion, die die Kommandozeilenargumente | |
379 verarbeitet, gibt es im Normalfall eine Funktion, die die | |
13 | 380 Feldauswahl in eine interne Datenstruktur ueberfuehrt. Desweiteren |
11 | 381 haben fast alle Implementierungen separate Funktionen fuer die |
382 zwei bzw. drei Modi. Bei den POSIX-konformen Implementierungen | |
383 wird die `-b -n'-Kombination als weiterer Modus behandelt, und | |
384 damit in einer eigenen Funktion umgesetzt. Nur bei der fruehen | |
385 System III-Implementierung (und seiner 4.3BSD-UWisc-Variante) | |
13 | 386 wird ausser den Fehlerausgaben nichts aus der main-Funktion |
387 ausgelagert. | |
11 | 388 |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
389 Cut-Implementierungen haben typischerweise zwei limitierende |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
390 Groessen: Die Maximalanzahl unterstuetzter Felder und die maximale |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
391 Zeilenlaenge. Bei System III ist die Anzahl der moeglichen Felder |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
392 und ebenso die Zeilenlaenge auf 512 begrenzt. 4.3BSD-Reno und die |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
393 BSDs der 90er Jahre haben ebenfalls fixe Grenzen (_BSD_LINE_MAX |
12 | 394 bzw. _POSIX2_LINE_MAX). Bei modernen FreeBSDs, NetBSDs, bei |
395 allen GNU-Implementierungen und bei Heirloom kann sowohl | |
396 die Felderanzahl als auch die maximale Zeilenlaenge beliebig | |
397 gross werden; der Speicher dafür wird dynamisch alloziiert. | |
398 OpenBSD ist ein Hybrid aus fixer Maximalzahl an Feldern, aber | |
15
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
399 beliebiger Zeilenlaenge. XXX fgetln |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
400 Die begrenzte Felderanzahl scheint jedeoch kein praktisches |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
401 Problem darzustellen, da _POSIX2_LINE_MAX mit mindestens 2048 |
77d1f55bba08
Weitere Ueberarbeitungen
markus schnalke <meillo@marmaro.de>
parents:
13
diff
changeset
|
402 durchaus genug Platz bieten sollte. |
11 | 403 |
8 | 404 |
2 | 405 Beschreibungen |
406 | |
9 | 407 Interessant ist auch ein Vergleich der Kurzbeschreibungen von |
408 cut, wie sie sich in der Titelzeile von Manpages oder manchmal | |
409 auch am Anfang der Quellcodedatei finden. Die folgende Liste | |
410 ist grob zeitlich geordnet und nach Abstammung gruppiert: | |
3 | 411 |
412 | |
2 | 413 System III cut out selected fields of each line of a file |
3 | 414 System III (src) cut and paste columns of a table (projection of a relation) |
2 | 415 System V cut out selected fields of each line of a file |
416 HP-UX cut out (extract) selected fields of each line of a file | |
417 | |
3 | 418 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation) |
2 | 419 4.3BSD-Reno select portions of each line of a file |
420 NetBSD select portions of each line of a file | |
7 | 421 OpenBSD 4.6 select portions of each line of a file |
2 | 422 FreeBSD 1.0 select portions of each line of a file |
10 | 423 FreeBSD 10.0 cut out selected portions of each line of a file |
2 | 424 SunOS 4.1.3 remove selected fields from each line of a file |
425 SunOS 5.5.1 cut out selected fields of each line of a file | |
426 | |
8 | 427 Heirloom Tools cut out selected fields of each line of a file |
9 | 428 Heirloom Tools (src) cut out fields of lines of files |
2 | 429 |
430 GNU coreutils remove sections from each line of files | |
431 | |
432 Minix select out columns of a file | |
433 | |
434 Version 8 Unix rearrange columns of data | |
435 ``Unix Reader'' rearrange columns of text | |
1 | 436 |
9 | 437 POSIX cut out selected fields of each line of a file |
1 | 438 |
9 | 439 |
440 Die mit ``(src)'' markierten Beschreibungen sind aus dem | |
441 jeweiligen Quellcode entnommen. | |
442 Der POSIX-Eintrag enthaelt die Beschreibung des Standards. | |
443 Der ``Unix Reader'' ist ein rueckblickendes Textdokument von | |
5 | 444 Doug McIlroy, das das Auftreten von Tools in der Geschichte |
9 | 445 des Research Unix zum Thema hat. |
446 [ XXX | |
447 Eigentlich sollte seine | |
448 Beschreibung der in Version 8 Unix entsprechen. Die | |
449 Abweichung koennte sowohl ein Uebertragungsfehler als auch | |
450 eine nachtraegliche Korrektur sein. | |
451 Alle uebrigen Beschreibungen entstammen den Manpages. | |
5 | 452 |
9 | 453 Oft ist mit der Zeit die POSIX-Beschreibung uebernommen |
5 | 454 worden, wie beispielsweise bei FreeBSD zu sehen. |
455 [ https://svnweb.freebsd.org/base?view=revision&revision=167101 | |
9 | 456 XXX fixme! |
5 | 457 |
7 | 458 Interessant ist, dass die GNU coreutils seit Anbeginn vom |
5 | 459 Entfernen von Teilen der Eingabe sprechen, wohingegen die |
460 Kommandozeilenangabe klar ein Auswaehlen darstellt. Die | |
10 | 461 Worte ``cut out'' sind vielleicht auch nur etwas zu |
9 | 462 missverstaendlich. HP-UX hat sie deshalb praezisiert. |
5 | 463 |
10 | 464 Auch beim Begriff, was selektiert wird, ist man sich |
5 | 465 uneins. Die einen reden von Feldern (POSIX), andere von |
466 Abschnitten bzw. Teilen (BSD) und wieder andere von Spalten | |
467 (Research Unix). Ironischerweise leistet sich gerade Version | |
468 8 Unix, das eigentlich um eine sehr treffende Weltsicht | |
469 bemueht ist, mit ``rearrange columns of data'' die | |
470 unzutreffendste der Beschreibungen. | |
471 | |
472 | |
6 | 473 Autoreninfo |
474 | |
475 Markus Schnalke interessiert sich fuer die Hintergruende | |
476 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses | |
477 Textes wurde er regelrecht zum Historiker. | |
478 | |
479 | |
480 Lizenz | |
10 | 481 |
6 | 482 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported |
483 veroeffentlicht werden) |