6
|
1 Das Werkzeugkaestle, #1
|
0
|
2
|
6
|
3 cut - cut out selected fields of each line of a file
|
|
4 ----------------------------------------------------
|
|
5 markus schnalke <meillo@marmaro.de>
|
|
6 2015-05
|
0
|
7
|
|
8
|
1
|
9 Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
|
0
|
10 In keinem ordentlichen Tutorial zur Shellprogrammierung darf
|
|
11 es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt
|
4
|
12 fuer's Shellscripting. Hier will ich ein wenig hinter die
|
|
13 Fassade schauen.
|
0
|
14
|
|
15
|
4
|
16 Funktionsweise
|
|
17
|
|
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
|
0
|
21 bestimmte durch Trennzeichen definierte Felder.
|
|
22
|
4
|
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:
|
0
|
27
|
4
|
28 $ ls -l foo | cut -c 2-4
|
|
29 rw-
|
0
|
30
|
4
|
31 Oder die Schreibrechte des Besitzers, der Gruppe und der
|
|
32 Welt:
|
0
|
33
|
4
|
34 $ ls -l | cut -c 3,6,9
|
|
35 ww-
|
0
|
36
|
4
|
37 Mit cut lassen sich aber auch Strings kuerzen.
|
0
|
38
|
6
|
39 $ echo "$long" | cut -c -20
|
0
|
40
|
4
|
41 Dieser Befehl gibt die ersten maximal 20 Zeichen (jeder
|
|
42 Zeile) von `$long' aus.
|
0
|
43
|
4
|
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
|
0
|
54 Newline-Zeichen stehen haben (und den Rest stillschweigend
|
|
55 ignorieren), dann macht man das mit:
|
|
56
|
6
|
57 $ cut -b -500
|
0
|
58
|
4
|
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
|
0
|
64
|
|
65 Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den
|
|
66 interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm
|
4
|
67 koennen Felder ausgewaehlt werden. Das Trennzeichen (per
|
|
68 Default der Tab) kann mit `-d' geaendert werden.
|
0
|
69
|
|
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:
|
|
73
|
6
|
74 $ cut -d: -f1,3,6 /etc/passwd
|
0
|
75
|
|
76 (Die Argumente fuer die Optionen koennen bei cut uebrigens
|
|
77 direkt angehaengt oder mit Whitespace abgetrennt folgen.)
|
|
78
|
|
79
|
4
|
80 Dieser Feld-Modus ist fuer einfache tabellarische Dateien,
|
|
81 wie eben die passwd, gut geeignet. Er kommt aber schnell an
|
0
|
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
|
4
|
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.
|
0
|
94
|
4
|
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.
|
0
|
104
|
|
105
|
|
106 Geschichtliches
|
|
107
|
4
|
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.
|
1
|
112 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
|
4
|
113 Das ist die aelteste Manifestation des Programms, die ich
|
|
114 aufstoebern konnte.
|
0
|
115
|
1
|
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
|
6
|
118 Spezialversion 4.3BSD-UWisc,
|
|
119 [ http://gunkies.org/wiki/4.3_BSD_NFS_Wisconsin_Unix
|
|
120 die im Januar 1987 veroeffentlicht wurde.
|
1
|
121 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
|
4
|
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.
|
1
|
127 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
|
4
|
128 Seine Manpage
|
1
|
129 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
|
4
|
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.
|
0
|
138
|
1
|
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,
|
4
|
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
|
1
|
155 anzutreffen.
|
|
156
|
5
|
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.
|
2
|
162
|
|
163
|
|
164 Beschreibungen
|
|
165
|
|
166 Interessant ist ein Vergleich der Kurzbeschreibungen von cut,
|
3
|
167 wie sie sich in der Titelzeile von Manpages oder manchmal auch
|
5
|
168 am Anfang der Quellcodedatei finden.
|
2
|
169
|
5
|
170 Die folgende Liste ist grob nach Zeit geordnet und nach
|
|
171 Abstammung gruppiert:
|
3
|
172
|
|
173
|
2
|
174 System III cut out selected fields of each line of a file
|
3
|
175 System III (src) cut and paste columns of a table (projection of a relation)
|
2
|
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
|
|
178
|
3
|
179 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
|
2
|
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
|
3
|
183 FreeBSD 7.0 cut out selected portions of each line of a file
|
2
|
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
|
|
186
|
|
187 POSIX cut out selected fields of each line of a file
|
|
188
|
|
189 GNU coreutils remove sections from each line of files
|
|
190
|
|
191 Minix select out columns of a file
|
|
192
|
|
193 Version 8 Unix rearrange columns of data
|
|
194 ``Unix Reader'' rearrange columns of text
|
1
|
195
|
|
196
|
5
|
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.
|
|
204
|
|
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
|
|
208
|
|
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.
|
|
214
|
|
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.
|
|
222
|
|
223
|
1
|
224
|
3
|
225 Codevergleich
|
2
|
226
|
|
227
|
|
228
|
5
|
229
|
6
|
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
|
|
241
|
|
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
|
|
254
|
|
255 (* == version hat -b)
|
|
256
|
|
257
|
5
|
258
|
|
259
|
|
260 cut(1) in Version 8 Unix
|
|
261 ``In data base parlance, it projects a relation.''
|
6
|
262
|
|
263
|
|
264
|
|
265 Autoreninfo
|
|
266
|
|
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.
|
|
270
|
|
271
|
|
272 Lizenz
|
|
273 CC0 (und kann damit auch unter CC BY-SA 4.0 Unported
|
|
274 veroeffentlicht werden)
|