docs/cut

view cut.txt @ 6:bf2ac5df0063

Zwischenstand
author markus schnalke <meillo@marmaro.de>
date Sun, 03 May 2015 18:08:00 +0200
parents 00097c80a853
children 21ca59543b07
line source
1 Das Werkzeugkaestle, #1
3 cut - cut out selected fields of each line of a file
4 ----------------------------------------------------
5 markus schnalke <meillo@marmaro.de>
6 2015-05
9 Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
10 In keinem ordentlichen Tutorial zur Shellprogrammierung darf
11 es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt
12 fuer's Shellscripting. Hier will ich ein wenig hinter die
13 Fassade schauen.
16 Funktionsweise
18 Die Funktionsbasis von cut waren urspruenglich zwei Modi, die
19 spaeter um einen dritten erweitert wurden. Cut schneidet
20 entweder bestimmte Zeichen aus den Zeilen der Eingabe oder
21 bestimmte durch Trennzeichen definierte Felder.
23 Der Zeichenmodus ist geeignet um Ausschnitte aus
24 Festbreitenformaten zu extrahieren. So kann man damit
25 beispielsweise bestimmte Zugriffsrechte aus der Ausgabe von
26 `ls -l' ausschneiden. Hier die Rechte des Besitzers:
28 $ ls -l foo | cut -c 2-4
29 rw-
31 Oder die Schreibrechte des Besitzers, der Gruppe und der
32 Welt:
34 $ ls -l | cut -c 3,6,9
35 ww-
37 Mit cut lassen sich aber auch Strings kuerzen.
39 $ echo "$long" | cut -c -20
41 Dieser Befehl gibt die ersten maximal 20 Zeichen (jeder
42 Zeile) von `$long' aus.
44 Geht es aber nicht um die Darstellung von Zeichen, sondern um
45 ihre Speicherung, dann ist `-c' nicht unbedingt die passende
46 Option. Frueher, als US-ASCII als Zeichensatz und -kodierung
47 noch omnipraesent war, wurde jedes Zeichen mit genau einem
48 Byte gespeichert. Somit selektierte `cut -c' gleichermassen
49 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
50 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
51 dieser Annahme loesen. In diesem Zug bekam cut mit
52 POSIX.2-1992 die Option `-b'. Diese selektiert Bytes. Will man
53 also nur die ersten maximal 500 Bytes vor dem
54 Newline-Zeichen stehen haben (und den Rest stillschweigend
55 ignorieren), dann macht man das mit:
57 $ cut -b -500
59 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese
60 Funktion ist insbesondere fuer POSIX wichtig, da so sicher
61 gestellt werden kann, dass Textdateien keine beliebig
62 langen Zeilen haben.
63 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17
65 Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den
66 interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm
67 koennen Felder ausgewaehlt werden. Das Trennzeichen (per
68 Default der Tab) kann mit `-d' geaendert werden.
70 Der typische Anwendungsfall fuer den Feld-Modus. Ist die
71 Extraktion von Information aus der passwd-Datei. So z.B. der
72 Username, die User-ID und das Homeverzeichnis:
74 $ cut -d: -f1,3,6 /etc/passwd
76 (Die Argumente fuer die Optionen koennen bei cut uebrigens
77 direkt angehaengt oder mit Whitespace abgetrennt folgen.)
80 Dieser Feld-Modus ist fuer einfache tabellarische Dateien,
81 wie eben die passwd, gut geeignet. Er kommt aber schnell an
82 seine Grenzen. Gerade der uebliche Fall, dass an Whitespace
83 in Felder geteilt werden soll, wird damit nicht abgedeckt.
84 Der Delimiter kann nur genau ein Zeichen sein. Es kann also
85 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden.
86 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander
87 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses
88 Verhalten widerspricht den Erwartungen fuer eine Datei mit
89 Whitespace-getrennten Feldern. (Manche Implementierungen von
90 cut, z.B. die von FreeBSD, haben deshalb Erweiterungen, die
91 das gewuenschte Verhalten fuer Whitespace-getrennte Felder
92 bieten.) Ansonsten, d.h. wenn man portabel bleiben will,
93 hilft awk.
95 Awk bietet noch eine weitere Funktion, die cut missen
96 laesst: Das Tauschen der Felder-Reihenfolge. Bei cut ist die
97 Reihenfolge der Feldauswahl irrelevant; ein Feld kann selbst
98 mehrfach angegeben werden. Der Aufruf von `cut -c 5-8,1,4-6'
99 gibt z.B. die Zeichen Nummer 1, 4, 5, 6, 7 und 8 aus. Die
100 Auswahl aehnelt damit der Mengenlehre in der Mathematik:
101 Jedes angegebene Feld soll in der Ergebnismenge sein. Die
102 Felder der Ergebnismenge werden dabei immer in der gleichen
103 Reihenfolge ausgegeben wie sie in der Eingabe waren.
106 Geschichtliches
108 Cut erblickte 1982 mit dem Release von UNIX System III das
109 Licht der oeffentlichen Welt. Wenn man die Quellen von System
110 III durchforstet, findet man die Quellcodedatei cut.c mit dem
111 Zeitstempel 1980-04-11.
112 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
113 Das ist die aelteste Manifestation des Programms, die ich
114 aufstoebern konnte.
116 Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein
117 fruehester Fund ein cut.c mit dem Datum 1986-11-07 im Code der
118 Spezialversion 4.3BSD-UWisc,
119 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
120 die im Januar 1987 veroeffentlicht wurde.
121 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
122 Die Datei unterscheidet sich nur minimal von der aus System III.
123 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut aber nicht auf.
124 Im darauf folgenden 4.3BSD-Reno (1990) gibt es wiederum ein
125 cut ... ein von Adam S. Moskowitz und Marciano Pitargue neu
126 implementiertes cut, das 1989 in BSD aufgenommen wurde.
127 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
128 Seine Manpage
129 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
130 erwaehnt bereits die erwartete Konformitaet mit POSIX.2.
131 Nun sollte man wissen, dass POSIX.2 erst im September
132 1992 veroeffentlicht wurde, gut zwei Jahren *nachdem* die
133 Manpage und das Programm geschrieben wurden. Dieses cut
134 wurde also anhand von Entwuerfen des Standards
135 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in
136 den Standardisierungsprozess geflossen; bis zur
137 Fertigstellung sollte es noch weitere zwei Jahre dauern.
139 Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut
140 aus Sicht des urspruenglichen Unix zu den juengeren Tools.
141 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist,
142 so war Unix doch schon ueber zehn Jahre alt, als cut das
143 erste Mal auftauchte. Insbesondere gehoerte cut noch nicht
144 zu Version 7 Unix, das die Ausgangsbasis aller modernen
145 Unix-Systeme darstellt. Die weit komplexeren Programme sed
146 und awk waren dort schon vertreten. Man muss sich also
147 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es
148 schon zwei Programme gab, die die Aufgabe von cut bereits
149 abdeckten. Ein Argument fuer cut ist seine Kompaktheit und
150 die damit verbundene Geschwindigkeit gegenueber dem damals
151 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix
152 Philosopie entspricht: Mache eine Aufgabe und die richtig!
153 So bewaehrte sich cut. Es wurde in andere Unix Varianten
154 uebernommen, standardisiert und ist heutzutage ueberall
155 anzutreffen.
157 Die urspruengliche Variante (ohne -b) taucht schon 1985 in
158 der System V Interface Definition, einer wichtigen formalen
159 Beschreibung von UNIX System V, und in allen relevanten
160 Standards seither auf. Mit POSIX.2 im Jahre 1992 wurde cut
161 zum ersten Mal in der heutigen Form (mit -b) standardisiert.
164 Beschreibungen
166 Interessant ist ein Vergleich der Kurzbeschreibungen von cut,
167 wie sie sich in der Titelzeile von Manpages oder manchmal auch
168 am Anfang der Quellcodedatei finden.
170 Die folgende Liste ist grob nach Zeit geordnet und nach
171 Abstammung gruppiert:
174 System III cut out selected fields of each line of a file
175 System III (src) cut and paste columns of a table (projection of a relation)
176 System V cut out selected fields of each line of a file
177 HP-UX cut out (extract) selected fields of each line of a file
179 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
180 4.3BSD-Reno select portions of each line of a file
181 NetBSD select portions of each line of a file
182 FreeBSD 1.0 select portions of each line of a file
183 FreeBSD 7.0 cut out selected portions of each line of a file
184 SunOS 4.1.3 remove selected fields from each line of a file
185 SunOS 5.5.1 cut out selected fields of each line of a file
187 POSIX cut out selected fields of each line of a file
189 GNU coreutils remove sections from each line of files
191 Minix select out columns of a file
193 Version 8 Unix rearrange columns of data
194 ``Unix Reader'' rearrange columns of text
197 Die zwei mit ``(src)'' markierten Beschreibungen sind aus
198 dem Quellcode entnommen, und verdeutlichen den Codetransfer.
199 POSIX ist ein Set von Standards, keine Implementierung. Der
200 ``Unix Reader'' ist ein rueckblickendes Textdokument von
201 Doug McIlroy, das das Auftreten von Tools in der Geschichte
202 des Research Unix zum Thema hat. Alle uebrigen Beschreibungen
203 entstammen den Manpages.
205 Zumeist ist mit der Zeit die POSIX-Beschreibung uebernommen
206 worden, wie beispielsweise bei FreeBSD zu sehen.
207 [ https://svnweb.freebsd.org/base?view=revision&revision=167101
209 Interessant ist, dass die GNU coreutils unveraendert vom
210 Entfernen von Teilen der Eingabe sprechen, wohingegen die
211 Kommandozeilenangabe klar ein Auswaehlen darstellt. Die
212 Worte ``cut out'' sind vielleicht auch nicht klar genug.
213 HP-UX hat sie deshalb praezisiert.
215 Auch beim Begriff, was denn nun selektiert wird, ist man sich
216 uneins. Die einen reden von Feldern (POSIX), andere von
217 Abschnitten bzw. Teilen (BSD) und wieder andere von Spalten
218 (Research Unix). Ironischerweise leistet sich gerade Version
219 8 Unix, das eigentlich um eine sehr treffende Weltsicht
220 bemueht ist, mit ``rearrange columns of data'' die
221 unzutreffendste der Beschreibungen.
225 Codevergleich
230 B-) wc -lc cut.c* | sort -n
231 123 2966 cut.c__system_iii.1980-04-11
232 125 3038 cut.c__4.3bsd-uwisc.1986-11-07
233 256 5715 cut.c__4.3bsd-reno.1990-06-25
234 270 6545 cut.c__netbsd.1993-03-21
235 296 6920 cut.c__freebsd.1994-05-27
236 306 7500 cut.c__netbsd.2014-02-03 *
237 479 10961 cut.c__freebsd.2012-11-24 *
238 586 14175 cut.c__gnu.1992-11-08 *
239 830 23167 cut.c__gnu.2015-05-01 *
240 3271 80987 total
242 B-) c_count cut.c* | sort -n
243 Total:
244 116 cut.c__system_iii.1980-04-11
245 118 cut.c__4.3bsd-uwisc.1986-11-07
246 200 cut.c__4.3bsd-reno.1990-06-25
247 200 cut.c__netbsd.1993-03-21
248 224 cut.c__freebsd.1994-05-27
249 232 cut.c__netbsd.2014-02-03 *
250 382 cut.c__gnu.1992-11-08 *
251 391 cut.c__freebsd.2012-11-24 *
252 588 cut.c__gnu.2015-05-01 *
253 2451
255 (* == version hat -b)
260 cut(1) in Version 8 Unix
261 ``In data base parlance, it projects a relation.''
265 Autoreninfo
267 Markus Schnalke interessiert sich fuer die Hintergruende
268 von Unix und seinen Werkzeugen. Fuer die Erarbeitung dieses
269 Textes wurde er regelrecht zum Historiker.
272 Lizenz
273 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported
274 veroeffentlicht werden)