Mercurial > docs > cut
comparison cut.txt @ 8:1dc4a9dca829
Zwischenstand
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 05 May 2015 09:04:00 +0200 |
parents | 21ca59543b07 |
children | e67bd0d48bd6 |
comparison
equal
deleted
inserted
replaced
7:21ca59543b07 | 8:1dc4a9dca829 |
---|---|
5 markus schnalke <meillo@marmaro.de> | 5 markus schnalke <meillo@marmaro.de> |
6 2015-05 | 6 2015-05 |
7 | 7 |
8 | 8 |
9 Cut ist ein klassisches Programm im Unix-Werkzeugkasten. | 9 Cut ist ein klassisches Programm im Unix-Werkzeugkasten. |
10 In keinem ordentlichen Tutorial zur Shellprogrammierung darf | 10 In keinem ordentlichen Tutorial zur Shellprogrammierung fehlt |
11 es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt | 11 es. Es ist ein schoenes Anschauungsobjekt fuer's Shellscripting. |
12 fuer's Shellscripting. Hier will ich ein wenig hinter die | 12 Hier soll ein wenig hinter die Fassade von cut geschaut werden. |
13 Fassade schauen. | |
14 | 13 |
15 | 14 |
16 Funktionsweise | 15 Funktionsweise |
17 | 16 |
18 Die Funktionsbasis von cut waren urspruenglich zwei Modi, die | 17 Urspruenglich hatte cut zwei Modi, die spaeter um einen dritten |
19 spaeter um einen dritten erweitert wurden. Cut schneidet | 18 erweitert wurden. Cut schneidet entweder bestimmte Zeichen aus |
20 entweder bestimmte Zeichen aus den Zeilen der Eingabe oder | 19 den Zeilen der Eingabe oder bestimmte, durch Trennzeichen |
21 bestimmte durch Trennzeichen definierte Felder. | 20 definierte, Felder. |
22 | 21 |
23 Der Zeichenmodus ist geeignet um Ausschnitte aus | 22 Der Zeichenmodus ist geeignet um Festbreitenformaten zu |
24 Festbreitenformaten zu extrahieren. So kann man damit | 23 zerteilen. So kann man damit beispielsweise bestimmte |
25 beispielsweise bestimmte Zugriffsrechte aus der Ausgabe von | 24 Zugriffsrechte aus der Ausgabe von `ls -l' ausschneiden. Hier |
26 `ls -l' ausschneiden. Hier die Rechte des Besitzers: | 25 die Rechte des Besitzers: |
27 | 26 |
28 $ ls -l foo | cut -c 2-4 | 27 $ ls -l foo | cut -c 2-4 |
29 rw- | 28 rw- |
30 | 29 |
31 Oder die Schreibrechte des Besitzers, der Gruppe und der | 30 Oder die Schreibrechte des Besitzers, der Gruppe und der |
36 | 35 |
37 Mit cut lassen sich aber auch Strings kuerzen. | 36 Mit cut lassen sich aber auch Strings kuerzen. |
38 | 37 |
39 $ echo "$long" | cut -c -20 | 38 $ echo "$long" | cut -c -20 |
40 | 39 |
41 Dieser Befehl gibt die ersten maximal 20 Zeichen (jeder | 40 Dieser Befehl gibt die ersten maximal 20 Zeichen von |
42 Zeile) von `$long' aus. | 41 `$long' aus. (Alternativ kann man hierfuer auch `printf |
42 "%.20s\n" "$long"' verwenden.) | |
43 | 43 |
44 Geht es aber nicht um die Darstellung von Zeichen, sondern um | 44 Geht es aber nicht um die Darstellung von Zeichen, sondern um |
45 ihre Speicherung, dann ist `-c' nicht unbedingt die passende | 45 ihre Speicherung, dann ist `-c' nicht unbedingt geeignet. |
46 Option. Frueher, als US-ASCII als Zeichensatz und -kodierung | 46 Frueher, als US-ASCII als Zeichensatz und -kodierung |
47 noch omnipraesent war, wurde jedes Zeichen mit genau einem | 47 noch omnipraesent war, wurde jedes Zeichen mit genau einem |
48 Byte gespeichert. Somit selektierte `cut -c' gleichermassen | 48 Byte gespeichert. Somit selektierte `cut -c' gleichermassen |
49 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von | 49 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von |
50 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von | 50 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von |
51 dieser Annahme loesen. In diesem Zug bekam cut mit | 51 dieser Annahme loesen. In diesem Zug bekam cut mit |
52 POSIX.2-1992 die Option `-b'. Diese selektiert Bytes. Will man | 52 POSIX.2-1992 einen Bytemodus mit der Option `-b'. Will man |
53 also nur die ersten maximal 500 Bytes vor dem | 53 also nur die ersten maximal 500 Bytes vor dem |
54 Newline-Zeichen stehen haben (und den Rest stillschweigend | 54 Newline-Zeichen stehen haben (und den Rest stillschweigend |
55 ignorieren), dann macht man das mit: | 55 ignorieren), dann macht man das mit: |
56 | 56 |
57 $ cut -b -500 | 57 $ cut -b -500 |
58 | 58 |
59 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese | 59 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese |
60 Funktion ist insbesondere fuer POSIX wichtig, da so sicher | 60 Funktion ist insbesondere fuer POSIX wichtig, da man so |
61 gestellt werden kann, dass Textdateien keine beliebig | 61 Textdateien mit begrenzter Zeilenlaenge erzeugen kann. |
62 langen Zeilen haben. | |
63 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17 | 62 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17 |
64 | 63 |
65 Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den | 64 Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den |
66 interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm | 65 Feld-Modus, den man mit `-f' einleitet. Mit ihm |
67 koennen Felder ausgewaehlt werden. Das Trennzeichen (per | 66 koennen Felder ausgewaehlt werden. Das Trennzeichen (per |
68 Default der Tab) kann mit `-d' geaendert werden. | 67 Default der Tab) kann mit `-d' geaendert werden. |
69 | 68 |
70 Der typische Anwendungsfall fuer den Feld-Modus. Ist die | 69 Der typische Anwendungsfall fuer cut im Feld-Modus ist die |
71 Extraktion von Information aus der passwd-Datei. So z.B. der | 70 Auswahl von Information aus der passwd-Datei. So z.B. der |
72 Username, die User-ID und das Homeverzeichnis: | 71 Benutername, seine ID und das Homeverzeichnis: |
73 | 72 |
74 $ cut -d: -f1,3,6 /etc/passwd | 73 $ cut -d: -f1,3,6 /etc/passwd |
75 | 74 |
76 (Die Argumente fuer die Optionen koennen bei cut uebrigens | 75 (Die Argumente fuer die Optionen koennen bei cut uebrigens |
77 direkt angehaengt oder mit Whitespace abgetrennt folgen.) | 76 mit Whitespace abgetrennt oder direkt angehaengt folgen.) |
78 | 77 |
79 | 78 |
80 Dieser Feld-Modus ist fuer einfache tabellarische Dateien, | 79 Dieser Feld-Modus ist fuer einfache tabellarische Dateien, |
81 wie eben die passwd, gut geeignet. Er kommt aber schnell an | 80 wie eben die passwd, gut geeignet. Er kommt aber schnell an |
82 seine Grenzen. Gerade der uebliche Fall, dass an Whitespace | 81 seine Grenzen. Gerade der uebliche Fall, dass an Whitespace |
83 in Felder geteilt werden soll, wird damit nicht abgedeckt. | 82 in Felder geteilt werden soll, wird damit nicht abgedeckt. |
84 Der Delimiter kann nur genau ein Zeichen sein. Es kann also | 83 Der Delimiter kann nur genau ein Zeichen sein. Es kann also |
85 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden. | 84 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden. |
86 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander | 85 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander |
87 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses | 86 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses |
88 Verhalten widerspricht den Erwartungen fuer eine Datei mit | 87 Verhalten widerspricht den Erwartungen, die man an die |
89 Whitespace-getrennten Feldern. (Manche Implementierungen von | 88 Verarbeitung einer Datei mit Whitespace-getrennten Feldern |
90 cut, z.B. die von FreeBSD, haben deshalb Erweiterungen, die | 89 hat. Manche Implementierungen von cut, z.B. die von FreeBSD, |
91 das gewuenschte Verhalten fuer Whitespace-getrennte Felder | 90 haben Erweiterungen, die das gewuenschte Verhalten fuer |
92 bieten.) Ansonsten, d.h. wenn man portabel bleiben will, | 91 Whitespace-getrennte Felder bieten. Ansonsten, d.h. wenn |
93 hilft awk. | 92 man portabel bleiben will, hilft awk. |
94 | 93 |
95 Awk bietet noch eine weitere Funktion, die cut missen | 94 Awk bietet noch eine weitere Funktion, die cut missen |
96 laesst: Das Tauschen der Felder-Reihenfolge. Bei cut ist die | 95 laesst: Das Tauschen der Feld-Reihenfolge in der Ausgabe. Bei |
97 Reihenfolge der Feldauswahl irrelevant; ein Feld kann selbst | 96 cut ist die Reihenfolge der Feldauswahlangabe irrelevant; ein |
98 mehrfach angegeben werden. Der Aufruf von `cut -c 5-8,1,4-6' | 97 Feld kann selbst mehrfach angegeben werden. So gibt der Aufruf |
99 gibt z.B. die Zeichen Nummer 1, 4, 5, 6, 7 und 8 aus. Die | 98 von `cut -c 5-8,1,4-6' die Zeichen Nummer 1, 4, 5, 6, 7 und 8 |
100 Auswahl aehnelt damit der Mengenlehre in der Mathematik: | 99 in genau dieser Reihenfolge aus. Die Auswahl entspricht damit |
101 Jedes angegebene Feld soll in der Ergebnismenge sein. Die | 100 der Mengenlehre in der Mathematik: Jedes angegebene Feld wird |
102 Felder der Ergebnismenge werden dabei immer in der gleichen | 101 Teil der Ergebnismenge sein. Die Felder der Ergebnismenge sind |
103 Reihenfolge ausgegeben wie sie in der Eingabe waren. | 102 dabei immer gleich geordnet wie sie es in der Eingabe waren. |
104 | 103 Oder, um die Worte der Manpage in Version 8 Unix |
105 | 104 wiederzugeben: ``In data base parlance, it projects a relation.'' |
106 | 105 Cut fuehrt also die Datenbankoperation Projektion auf |
107 cut(1) in Version 8 Unix | 106 Textdateien aus. Die Wikipedia erklaert das in |
108 ``In data base parlance, it projects a relation.'' | 107 verstaendlicherer Sprache: |
109 | |
110 WP: | |
111 http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion | |
112 | 108 |
113 Die Projektion entspricht der Projektionsabbildung aus der | 109 Die Projektion entspricht der Projektionsabbildung aus der |
114 Mengenlehre und kann auch Attributbeschränkung genannt | 110 Mengenlehre und kann auch Attributbeschränkung genannt |
115 werden. Sie extrahiert einzelne Attribute aus der | 111 werden. Sie extrahiert einzelne Attribute aus der |
116 ursprünglichen Attributmenge und ist somit als eine Art | 112 ursprünglichen Attributmenge und ist somit als eine Art |
117 Selektion auf Spaltenebene zu verstehen, das heißt, die | 113 Selektion auf Spaltenebene zu verstehen, das heißt, die |
118 Projektion blendet Spalten aus. | 114 Projektion blendet Spalten aus. |
119 | 115 |
116 [ http://de.wikipedia.org/wiki/Projektion_(Informatik)#Projektion | |
117 | |
120 | 118 |
121 | 119 |
122 | 120 |
123 Geschichtliches | 121 Geschichtliches |
124 | 122 |
126 Licht der oeffentlichen Welt. Wenn man die Quellen von System | 124 Licht der oeffentlichen Welt. Wenn man die Quellen von System |
127 III durchforstet, findet man die Quellcodedatei cut.c mit dem | 125 III durchforstet, findet man die Quellcodedatei cut.c mit dem |
128 Zeitstempel 1980-04-11. | 126 Zeitstempel 1980-04-11. |
129 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd | 127 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd |
130 Das ist die aelteste Manifestation des Programms, die ich | 128 Das ist die aelteste Manifestation des Programms, die ich |
131 aufstoebern konnte. | 129 aufstoebern konnte. Allerdings spricht die sccsid im |
130 Quellcode von Version 1.5. Es muss also noch eine | |
131 Vorgeschichte geben. Zu dieser habe ich leider keinen Zugang | |
132 gefunden. | |
132 | 133 |
133 Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein | 134 Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein |
134 fruehester Fund ein cut.c mit dem Datum 1986-11-07 im Code der | 135 fruehester Fund ein cut.c mit dem Dateimodifikationsdatum |
135 Spezialversion 4.3BSD-UWisc, | 136 1986-11-07 |
137 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut | |
138 als Teil der Spezialversion 4.3BSD-UWisc, | |
136 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix | 139 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix |
137 die im Januar 1987 veroeffentlicht wurde. | 140 die im Januar 1987 veroeffentlicht wurde. |
138 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut | 141 Die Implementierung unterscheidet sich nur minimal von der |
139 Die Datei unterscheidet sich nur minimal von der aus System III. | 142 in System III. |
140 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut aber nicht auf. | 143 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut nicht auf. |
141 Im darauf folgenden 4.3BSD-Reno (1990) gibt es wiederum ein | 144 Das darauf folgende 4.3BSD-Reno (1990) liefert aber wieder |
142 cut ... ein von Adam S. Moskowitz und Marciano Pitargue neu | 145 ein cut mit aus. Dieses cut ist ein von Adam S. Moskowitz und |
143 implementiertes cut, das 1989 in BSD aufgenommen wurde. | 146 Marciano Pitargue neu implementiertes cut, das 1989 in BSD |
147 aufgenommen wurde. | |
144 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut | 148 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut |
145 Seine Manpage | 149 Seine Manpage |
146 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1 | 150 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1 |
147 erwaehnt bereits die erwartete Konformitaet mit POSIX.2. | 151 erwaehnt bereits die erwartete Konformitaet mit POSIX.2. |
148 Nun sollte man wissen, dass POSIX.2 erst im September | 152 Nun sollte man wissen, dass POSIX.2 erst im September |
149 1992 veroeffentlicht wurde, gut zwei Jahren *nachdem* die | 153 1992 veroeffentlicht wurde, also gut zwei Jahren *nachdem* die |
150 Manpage und das Programm geschrieben wurden. Dieses cut | 154 Manpage und das Programm geschrieben wurden. Das Programm |
151 wurde also anhand von Entwuerfen des Standards | 155 wurde also anhand von Arbeitsversionen des Standards |
152 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in | 156 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in |
153 den Standardisierungsprozess geflossen; bis zur | 157 den Standardisierungsprozess geflossen; bis zur |
154 Fertigstellung sollte es noch weitere zwei Jahre dauern. | 158 Fertigstellung sollte es aber noch weitere zwei Jahre dauern. |
155 | 159 |
156 Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut | 160 Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut |
157 aus Sicht des urspruenglichen Unix zu den juengeren Tools. | 161 aus Sicht des urspruenglichen Unix zu den juengeren Tools. |
158 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist, | 162 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist, |
159 so war Unix doch schon ueber zehn Jahre alt, als cut das | 163 so war Unix doch schon ueber zehn Jahre alt, als cut das |
160 erste Mal auftauchte. Insbesondere gehoerte cut noch nicht | 164 erste Mal auftauchte. Insbesondere gehoerte cut noch nicht |
161 zu Version 7 Unix, das die Ausgangsbasis aller modernen | 165 zu Version 7 Unix, das die Ausgangsbasis aller modernen |
162 Unix-Systeme darstellt. Die weit komplexeren Programme sed | 166 Unix-Systeme darstellt. Die weit komplexeren Programme sed |
163 und awk waren dort schon vertreten. Man muss sich also | 167 und awk waren dort schon vertreten. Man muss sich also |
164 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es | 168 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es |
165 schon zwei Programme gab, die die Aufgabe von cut bereits | 169 schon zwei Programme gab, die die Aufgabe von cut abdeckten. |
166 abdeckten. Ein Argument fuer cut ist seine Kompaktheit und | 170 Ein Argument fuer cut war sicher seine Kompaktheit und |
167 die damit verbundene Geschwindigkeit gegenueber dem damals | 171 die damit verbundene Geschwindigkeit gegenueber dem damals |
168 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix | 172 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix |
169 Philosopie entspricht: Mache eine Aufgabe und die richtig! | 173 Philosopie entspricht: Mache eine Aufgabe und die richtig! |
170 So bewaehrte sich cut. Es wurde in andere Unix Varianten | 174 So bewaehrte sich cut. Es wurde in andere Unix Varianten |
171 uebernommen, standardisiert und ist heutzutage ueberall | 175 uebernommen, standardisiert und ist heutzutage ueberall |
172 anzutreffen. | 176 anzutreffen. |
173 | 177 |
174 Die urspruengliche Variante (ohne -b) taucht schon 1985 in | 178 Die urspruengliche Variante (ohne -b) tauchte schon 1985 in |
175 der System V Interface Definition, einer wichtigen formalen | 179 der System V Interface Definition, einer wichtigen formalen |
176 Beschreibung von UNIX System V, und in allen relevanten | 180 Beschreibung von UNIX System V, und in allen relevanten |
177 Standards seither auf. Mit POSIX.2 im Jahre 1992 wurde cut | 181 Standards seither auf. Mit POSIX.2 im Jahre 1992 wurde cut |
178 zum ersten Mal in der heutigen Form (mit -b) standardisiert. | 182 zum ersten Mal in der heutigen Form (mit -b) standardisiert. |
183 | |
184 | |
185 | |
186 Multibyte-Behandlung | |
187 | |
188 Nun sind der Bytemodus und die damit verbundene | |
189 Multibyte-Verarbeitung des POSIX-Zeichenmodus bereits seit | |
190 1992 standardisiert, wie steht es aber mit deren Umsetzung? | |
191 Welche Versionen implementieren denn den POSIX korrekt? | |
192 Die Situation ist mehrschichtig. Es gibt traditionelle | |
193 Implementierungen, die nur -c und -f kennen. Dann gibt es | |
194 Implementierungen die zwar -b kennen, es aber nur als Alias | |
195 fuer -c handhaben. Diese Implementierungen funktionieren mit | |
196 Single-Byte-Encodings (z.B. US-ASCII, Latin1) korrekt, bei | |
197 Multi-Byte-Encodings (z.B. UTF-8) verhaelt sich ihr -c aber | |
198 wie -b (und -n wird ignoriert). Schliesslich gibt es noch | |
199 Implementierungen, die -b und -c tatsaechlich POSIX-konform | |
200 implementieren. | |
201 | |
202 Traditionelle Zwei-Modi-Implementierungen sind z.B. die von | |
203 System III, System V und die aller BSDs bis in die 90er. | |
204 | |
205 Pseude-Multibyte-Implementierungen bieten GNU und die | |
206 modernen NetBSDs und OpenBSDs. Wie sehr dort der Schein von | |
207 POSIX-konformitaet gewahrt wird, ist unterschiedlich. Nicht | |
208 immer findet man klare Aussagen wie diese: | |
209 | |
210 /* Since we don't support multi-byte characters, the -c and -b | |
211 options are equivalent, and the -n option is meaningless. */ | |
212 | |
213 [ XXX | |
214 | |
215 Tatsaechlich standardkonforme Implementierungen, die | |
216 Multibytes korrekt handhaben, bekommt man bei einem modernen | |
217 FreeBSD und bei den Heirloom Tools. Bei FreeBSD hat Tim Robbins | |
218 (tjr) im Sommer 2004 den Zeichenmodus POSIX-konform reimplementiert. | |
219 [ https://svnweb.freebsd.org/base?view=revision&revision=131194 | |
220 Warum die beiden anderen grossen BSDs diese Aenderung nicht | |
221 uebernommen haben, bleibt offen. Es scheint aber an der im | |
222 obigen Kommentar formulierten Grundausrichtung zu liegen. | |
223 | |
224 Wie findet man als Nutzer heraus, ob beim cut(1) des eigenen | |
225 Systems Multibytes korrekt unterstuetzt werden? Zuerst ist | |
226 entscheidend, ob das System selbst mit einem Multibyte-Encoding | |
227 arbeitet, denn tut es das nicht, dann entsprechen sich Zeichen | |
228 und Bytes und die Frage eruebrigt sich. Man kann dazu nachschauen, | |
229 welches Locale eingestellt ist, aber einfacher ist es, ein | |
230 typisches Mehrbytezeichen, wie z.B. einen Umlaut, auszugeben | |
231 und zu schauen ob dieses in einem oder in mehreren Bytes | |
232 kodiert ist: | |
233 | |
234 $ echo ä | od -c | |
235 0000000 303 244 \n | |
236 0000003 | |
237 | |
238 In diesem Fall sind es zwei Bytes: oktal 303 und 244 . (Den | |
239 Zeilenumbruch fuegt echo(1) hinzu.) | |
240 | |
241 Mit dem Programm iconv(1) kann man Test explizit in bestimmte | |
242 Kodierungen konvertieren. Hier Beispiele, wie das Ergebnis | |
243 bei Latin1 und wie es bei UTF-8 aussieht. | |
244 | |
245 $ echo ä | iconv -t latin1 | od -c | |
246 0000000 344 \n | |
247 0000002 | |
248 | |
249 $ echo ä | iconv -t utf8 | od -c | |
250 0000000 303 244 \n | |
251 0000003 | |
252 | |
253 Die Ausgabe auf dem eigenen System (ohne die iconv-Konvertierung) | |
254 wird recht sicher einer dieser beiden Ausgaben entsprechen. | |
255 | |
256 Nun zum Test der cut-Implementierung. Hat man ein UTF-8-System, | |
257 dann sollte sich eine POSIX-konforme Implementierung so verhalten: | |
258 | |
259 $ echo aä | ./cut -c -2 | od -c | |
260 0000000 a 303 244 \n | |
261 0000004 | |
262 | |
263 $ echo aä | ./cut -b -2 | od -c | |
264 0000000 a 303 \n | |
265 0000003 | |
266 | |
267 $ echo aä | ./cut -b -2 -n | od -c | |
268 0000000 a \n | |
269 0000002 | |
270 | |
271 Bei einer Implementierung, die -b und -c gleich behandelt, | |
272 ist die Ausgabe in allen drei Faellen wie die mittlere: Es | |
273 werden die ersten beiden Bytes ausgegeben. | |
274 | |
275 | |
276 | |
277 Implementierungen | |
278 | |
279 Nun zum Blick auf den Code. Hier soll eine Auswahl an | |
280 Implementierungen etwas genauer betrachtet werden. Fuer einen | |
281 ersten Eindruck ist der Umfang des Quellcodes hilfreich. | |
282 Typischerweise steigt dieser ueber die Jahre an. Diese | |
283 Beobachtung kann hier in der Tendenz, aber nicht in jedem Fall, | |
284 bestaetigt werden. | |
285 | |
286 Die Unterstuetzung des Byte-Modus (-b) erfordert zwangslaeufig | |
287 mehr Code, deshalb ist zu erwarten, dass diejenigen | |
288 Implementierungen, die ihn haben, umfangreicher sind. | |
289 | |
290 Codevergleich | |
291 | |
292 SLOC Zeilen Bytes Gehoert zu Dateidatum Kategorie | |
293 ----------------------------------------------------------------- | |
294 116 123 2966 System III 1980-04-11 (trad) | |
295 118 125 3038 4.3BSD-UWisc 1986-11-07 (trad) | |
296 200 256 5715 4.3BSD-Reno 1990-06-25 (trad) | |
297 200 270 6545 NetBSD 1993-03-21 (trad) | |
298 218 290 6892 OpenBSD 2008-06-27 (pseudo) | |
299 224 296 6920 FreeBSD 1994-05-27 (trad) | |
300 232 306 7500 NetBSD 2014-02-03 (pseudo) | |
301 340 405 7423 Heirloom 2012-05-20 (POSIX) | |
302 382 586 14175 GNU coreutils 1992-11-08 (pseudo) | |
303 391 479 10961 FreeBSD 2012-11-24 (POSIX) | |
304 588 830 23167 GNU coreutils 2015-05-01 (pseudo) | |
305 | |
306 | |
307 $ awk -F' +' '{printf("%d\t%d (%.2f)\t%d (%.2f)\t%s\t%s\t%s\n", | |
308 $1, $2, $2/$1, $3, $3/$1, $4, $5, $6);}' <sloc | |
309 116 123 (1.06) 2966 (25.57) System III 1980-04-11 (trad) | |
310 118 125 (1.06) 3038 (25.75) 4.3BSD-UWisc 1986-11-07 (trad) | |
311 200 256 (1.28) 5715 (28.57) 4.3BSD-Reno 1990-06-25 (trad) | |
312 200 270 (1.35) 6545 (32.73) NetBSD 1993-03-21 (trad) | |
313 218 290 (1.33) 6892 (31.61) OpenBSD 2008-06-27 (pseudo) | |
314 224 296 (1.32) 6920 (30.89) FreeBSD 1994-05-27 (trad) | |
315 232 306 (1.32) 7500 (32.33) NetBSD 2014-02-03 (pseudo) | |
316 340 405 (1.19) 7423 (21.83) Heirloom 2012-05-20 (POSIX) | |
317 382 586 (1.53) 14175 (37.11) GNU coreutils 1992-11-08 (pseudo) | |
318 391 479 (1.23) 10961 (28.03) FreeBSD 2012-11-24 (POSIX) | |
319 588 830 (1.41) 23167 (39.40) GNU coreutils 2015-05-01 (pseudo) | |
320 | |
321 | |
322 Einige Auffaelligkeiten: | |
323 | |
324 Das Kandidatenfeld teilt sich grob in vier Gruppen: Die zwei urspruenglichen | |
325 Implementierungen, die sich nur minimal unterscheiden, mit gut 100 SLOCs. | |
326 Dann die fuenf BSD-Versionen mit knapp ueber 200 SLOCs. Anschliessend die | |
327 zwei POSIX-konformen Programme und die alte GNU-Version mit 350-400 | |
328 SLOCs. Und zum Abschluss die moderne GNU-Variante mit fast 600 SLOCs. | |
329 | |
330 Die Abweichung von logischen Codezeilen (nach der Definition von | |
331 SLOCcount) und der Anzahl von Zeilenumbruechen in der Datei erstreckt | |
332 sich ueber einen Faktor von 1.06 bei den aeltesten Vertretern bis zu | |
333 Faktor 1.5 bei GNU. | |
334 | |
335 Betrachtet man die Abweichungen zwischen den logischen Codezeilen und der | |
336 Dateigroesse, so pendelt das Teilnehmerfeld zwischen 25 und 30 Bytes je | |
337 Anweisung. Die Heirloom-Implementierung weicht nach unten ab, die | |
338 GNU-Implementierungen nach oben. | |
339 | |
340 | |
341 | |
342 Das cut in System III von 1980 ist, wie man anhand der SCCS-ID erkennen | |
343 kann bereits in Version 1.5. Die Vorversionen konnte ich aber leider nicht | |
344 ermitteln. | |
345 | |
346 Schaut man sich die SCCS-IDs in den BSD-Quellen an, dann findet man dort | |
347 Versionsnummern, die die Entwicklung dokumentieren: | |
348 | |
349 4.3bsd-uwisc "@(#)cut.c 1.3"; | |
350 4.3bsd-reno "@(#)cut.c 5.3 (Berkeley) 6/24/90"; | |
351 netbsd "@(#)cut.c 5.4 (Berkeley) 10/30/90"; | |
352 freebsd "@(#)cut.c 8.1 (Berkeley) 6/6/93"; | |
353 | |
354 Die neueren BSD-Versionen enthalten zwar weiterhin eine SCCS-ID, diese | |
355 ist aber bei Version "8.3 (Berkeley) 5/4/95" stehen geblieben. Danach | |
356 wurde scheinbar von SCCS auf CSV oder SVN gewechselt. | |
357 | |
358 Bei GNU befindet sich folgender Copyright-Vermerk im Code: | |
359 | |
360 Copyright (C) 1997-2015 Free Software Foundation, Inc. | |
361 Copyright (C) 1984 David M. Ihnat | |
362 | |
363 Wie aus weiteren Kommentaren zu entnehmen ist, wurde der Code von zuerst | |
364 von David MacKenzie und spaeter von Jim Meyering ueberarbeitet. Letzterer | |
365 hat den Code 1992 auch ins Versionkontrollsystem eingestellt. Weshalb | |
366 die Jahre zwischen 1992 und 1997 nicht im Copyright-Vermerk auftauchen, | |
367 ist unklar. | |
368 | |
369 | |
179 | 370 |
180 | 371 |
181 Beschreibungen | 372 Beschreibungen |
182 | 373 |
183 Interessant ist ein Vergleich der Kurzbeschreibungen von cut, | 374 Interessant ist ein Vergleich der Kurzbeschreibungen von cut, |
200 FreeBSD 1.0 select portions of each line of a file | 391 FreeBSD 1.0 select portions of each line of a file |
201 FreeBSD 7.0 cut out selected portions of each line of a file | 392 FreeBSD 7.0 cut out selected portions of each line of a file |
202 SunOS 4.1.3 remove selected fields from each line of a file | 393 SunOS 4.1.3 remove selected fields from each line of a file |
203 SunOS 5.5.1 cut out selected fields of each line of a file | 394 SunOS 5.5.1 cut out selected fields of each line of a file |
204 | 395 |
396 Heirloom Tools cut out selected fields of each line of a file | |
397 | |
205 POSIX cut out selected fields of each line of a file | 398 POSIX cut out selected fields of each line of a file |
206 | 399 |
207 GNU coreutils remove sections from each line of files | 400 GNU coreutils remove sections from each line of files |
208 | 401 |
209 Minix select out columns of a file | 402 Minix select out columns of a file |
238 bemueht ist, mit ``rearrange columns of data'' die | 431 bemueht ist, mit ``rearrange columns of data'' die |
239 unzutreffendste der Beschreibungen. | 432 unzutreffendste der Beschreibungen. |
240 | 433 |
241 | 434 |
242 | 435 |
243 Codevergleich | |
244 | |
245 Nun zum Blick auf den Code. Hier soll eine Auswahl an | |
246 Implementierungen etwas genauer betrachtet werden. Fuer einen | |
247 ersten Eindruck ist der Umfang des Quellcodes hilfreich. | |
248 Typischerweise steigt dieser ueber die Jahre an. Diese | |
249 Beobachtung kann hier in der Tendenz aber nicht in jedem Fall | |
250 bestaetigt werden. Die Unterstuetzung des Byte-Modus (-b) | |
251 erfordert zwangslaeufig mehr Code, deshalb ist zu erwarten, | |
252 dass | |
253 | |
254 -b pseudo: openbsd, netbsd.2014, gnu* | |
255 -b real: freebsd.2014 | |
256 | |
257 :-& echo '123ä56' | cut -c -6 | od -c | |
258 0000000 1 2 3 303 244 5 \n | |
259 0000007 | |
260 | |
261 :-& echo '123ä56' | cut -b -6 | od -c | |
262 0000000 1 2 3 303 244 5 \n | |
263 0000007 | |
264 | |
265 | |
266 $ wc -lc cut.c* | sort -n | |
267 123 2966 cut.c__system_iii.1980-04-11 | |
268 125 3038 cut.c__4.3bsd-uwisc.1986-11-07 | |
269 256 5715 cut.c__4.3bsd-reno.1990-06-25 | |
270 270 6545 cut.c__netbsd.1993-03-21 | |
271 290 6892 cut.c__openbsd.2008-06-27 * | |
272 296 6920 cut.c__freebsd.1994-05-27 | |
273 306 7500 cut.c__netbsd.2014-02-03 * | |
274 479 10961 cut.c__freebsd.2012-11-24 * | |
275 586 14175 cut.c__gnu.1992-11-08 * | |
276 830 23167 cut.c__gnu.2015-05-01 * | |
277 3271 80987 total | |
278 | |
279 $ c_count cut.c* | sort -n | |
280 Total: | |
281 116 cut.c__system_iii.1980-04-11 | |
282 118 cut.c__4.3bsd-uwisc.1986-11-07 | |
283 200 cut.c__4.3bsd-reno.1990-06-25 | |
284 200 cut.c__netbsd.1993-03-21 | |
285 218 cut.c__openbsd.2008-06-27 * | |
286 224 cut.c__freebsd.1994-05-27 | |
287 232 cut.c__netbsd.2014-02-03 * | |
288 382 cut.c__gnu.1992-11-08 * | |
289 391 cut.c__freebsd.2012-11-24 * | |
290 588 cut.c__gnu.2015-05-01 * | |
291 2451 | |
292 | |
293 (* == version hat -b) | |
294 | |
295 | |
296 | |
297 system_iii.1980-04-11 Release 1.5 | |
298 | |
299 SCCSIDs: | |
300 | |
301 4.3bsd-uwisc.1986-11-07 "@(#)cut.c 1.3"; | |
302 4.3bsd-reno.1990-06-25 "@(#)cut.c 5.3 (Berkeley) 6/24/90"; | |
303 netbsd.1993-03-21 "@(#)cut.c 5.4 (Berkeley) 10/30/90"; | |
304 freebsd.1994-05-27 "@(#)cut.c 8.1 (Berkeley) 6/6/93"; | |
305 | |
306 freebsd.2012-11-24 "@(#)cut.c 8.3 (Berkeley) 5/4/95"; | |
307 netbsd.2014-02-03 "@(#)cut.c 8.3 (Berkeley) 5/4/95"; | |
308 | |
309 openbsd.2008-06-27 "@(#)cut.c 8.3 (Berkeley) 5/4/95"; | |
310 "$OpenBSD: cut.c,v 1.13 2008/06/27 08:02:13 sobrado Exp $"; | |
311 | |
312 GNU | |
313 Copyright (C) 1997-2015 Free Software Foundation, Inc. | |
314 Copyright (C) 1984 David M. Ihnat | |
315 /* Written by David Ihnat. */ | |
316 | |
317 /* POSIX changes, bug fixes, long-named options, and cleanup | |
318 by David MacKenzie <djm@gnu.ai.mit.edu>. | |
319 | |
320 Rewrite cut_fields and cut_bytes -- Jim Meyering. */ | |
321 | |
322 1992-11-08 | |
323 Jim Meyering | |
324 | |
325 | |
326 | |
327 | |
328 | |
329 | 436 |
330 Autoreninfo | 437 Autoreninfo |
331 | 438 |
332 Markus Schnalke interessiert sich fuer die Hintergruende | 439 Markus Schnalke interessiert sich fuer die Hintergruende |
333 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses | 440 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses |