rev |
line source |
meillo@0
|
1 Das Werkzeugkaestle
|
meillo@0
|
2
|
meillo@0
|
3 #1: cut - cut out selected fields of each line of a file
|
meillo@0
|
4 ---------------------------------------------------------
|
meillo@4
|
5 markus schnalke, 2015-05
|
meillo@0
|
6
|
meillo@0
|
7
|
meillo@1
|
8 Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
|
meillo@0
|
9 In keinem ordentlichen Tutorial zur Shellprogrammierung darf
|
meillo@0
|
10 es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt
|
meillo@4
|
11 fuer's Shellscripting. Hier will ich ein wenig hinter die
|
meillo@4
|
12 Fassade schauen.
|
meillo@0
|
13
|
meillo@0
|
14
|
meillo@4
|
15 Funktionsweise
|
meillo@4
|
16
|
meillo@4
|
17 Die Funktionsbasis von cut waren urspruenglich zwei Modi, die
|
meillo@4
|
18 spaeter um einen dritten erweitert wurden. Cut schneidet
|
meillo@4
|
19 entweder bestimmte Zeichen aus den Zeilen der Eingabe oder
|
meillo@0
|
20 bestimmte durch Trennzeichen definierte Felder.
|
meillo@0
|
21
|
meillo@4
|
22 Der Zeichenmodus ist geeignet um Ausschnitte aus
|
meillo@4
|
23 Festbreitenformaten zu extrahieren. So kann man damit
|
meillo@4
|
24 beispielsweise bestimmte Zugriffsrechte aus der Ausgabe von
|
meillo@4
|
25 `ls -l' ausschneiden. Hier die Rechte des Besitzers:
|
meillo@0
|
26
|
meillo@4
|
27 $ ls -l foo | cut -c 2-4
|
meillo@4
|
28 rw-
|
meillo@0
|
29
|
meillo@4
|
30 Oder die Schreibrechte des Besitzers, der Gruppe und der
|
meillo@4
|
31 Welt:
|
meillo@0
|
32
|
meillo@4
|
33 $ ls -l | cut -c 3,6,9
|
meillo@4
|
34 ww-
|
meillo@0
|
35
|
meillo@4
|
36 Mit cut lassen sich aber auch Strings kuerzen.
|
meillo@0
|
37
|
meillo@4
|
38 echo "$long" | cut -c -20
|
meillo@0
|
39
|
meillo@4
|
40 Dieser Befehl gibt die ersten maximal 20 Zeichen (jeder
|
meillo@4
|
41 Zeile) von `$long' aus.
|
meillo@0
|
42
|
meillo@4
|
43 Geht es aber nicht um die Darstellung von Zeichen, sondern um
|
meillo@4
|
44 ihre Speicherung, dann ist `-c' nicht unbedingt die passende
|
meillo@4
|
45 Option. Frueher, als US-ASCII als Zeichensatz und -kodierung
|
meillo@4
|
46 noch omnipraesent war, wurde jedes Zeichen mit genau einem
|
meillo@4
|
47 Byte gespeichert. Somit selektierte `cut -c' gleichermassen
|
meillo@4
|
48 sowohl Ausgabezeichen als auch Bytes. Mit dem Aufkommen von
|
meillo@4
|
49 Multibyte-Kodierungen (wie UTF-8) musste man sich jedoch von
|
meillo@4
|
50 dieser Annahme loesen. In diesem Zug bekam cut mit
|
meillo@4
|
51 POSIX.2-1992 die Option `-b'. Diese selektiert Bytes. Will man
|
meillo@4
|
52 also nur die ersten maximal 500 Bytes vor dem
|
meillo@0
|
53 Newline-Zeichen stehen haben (und den Rest stillschweigend
|
meillo@0
|
54 ignorieren), dann macht man das mit:
|
meillo@0
|
55
|
meillo@4
|
56 cut -b -500
|
meillo@0
|
57
|
meillo@4
|
58 Den Rest kann man sich mit `cut -b 501-' einfangen. Diese
|
meillo@4
|
59 Funktion ist insbesondere fuer POSIX wichtig, da so sicher
|
meillo@4
|
60 gestellt werden kann, dass Textdateien keine beliebig
|
meillo@4
|
61 langen Zeilen haben.
|
meillo@4
|
62 [ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cut.html#tag_20_28_17
|
meillo@0
|
63
|
meillo@0
|
64 Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den
|
meillo@0
|
65 interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm
|
meillo@4
|
66 koennen Felder ausgewaehlt werden. Das Trennzeichen (per
|
meillo@4
|
67 Default der Tab) kann mit `-d' geaendert werden.
|
meillo@0
|
68
|
meillo@0
|
69 Der typische Anwendungsfall fuer den Feld-Modus. Ist die
|
meillo@0
|
70 Extraktion von Information aus der passwd-Datei. So z.B. der
|
meillo@0
|
71 Username, die User-ID und das Homeverzeichnis:
|
meillo@0
|
72
|
meillo@0
|
73 cut -d: -f1,3,6 /etc/passwd
|
meillo@0
|
74
|
meillo@0
|
75 (Die Argumente fuer die Optionen koennen bei cut uebrigens
|
meillo@0
|
76 direkt angehaengt oder mit Whitespace abgetrennt folgen.)
|
meillo@0
|
77
|
meillo@0
|
78
|
meillo@4
|
79 Dieser Feld-Modus ist fuer einfache tabellarische Dateien,
|
meillo@4
|
80 wie eben die passwd, gut geeignet. Er kommt aber schnell an
|
meillo@0
|
81 seine Grenzen. Gerade der uebliche Fall, dass an Whitespace
|
meillo@0
|
82 in Felder geteilt werden soll, wird damit nicht abgedeckt.
|
meillo@0
|
83 Der Delimiter kann nur genau ein Zeichen sein. Es kann also
|
meillo@0
|
84 nicht sowohl an Leerzeichen als auch an Tabs getrennt werden.
|
meillo@0
|
85 Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander
|
meillo@4
|
86 stehende Trennzeichen fuehren zu einem leeren Feld. Dieses
|
meillo@4
|
87 Verhalten widerspricht den Erwartungen fuer eine Datei mit
|
meillo@4
|
88 Whitespace-getrennten Feldern. (Manche Implementierungen von
|
meillo@4
|
89 cut, z.B. die von FreeBSD, haben deshalb Erweiterungen, die
|
meillo@4
|
90 das gewuenschte Verhalten fuer Whitespace-getrennte Felder
|
meillo@4
|
91 bieten.) Ansonsten, d.h. wenn man portabel bleiben will,
|
meillo@4
|
92 hilft awk.
|
meillo@0
|
93
|
meillo@4
|
94 Awk bietet noch eine weitere Funktion, die cut missen
|
meillo@4
|
95 laesst: Das Tauschen der Felder-Reihenfolge. Bei cut ist die
|
meillo@4
|
96 Reihenfolge der Feldauswahl irrelevant; ein Feld kann selbst
|
meillo@4
|
97 mehrfach angegeben werden. Der Aufruf von `cut -c 5-8,1,4-6'
|
meillo@4
|
98 gibt z.B. die Zeichen Nummer 1, 4, 5, 6, 7 und 8 aus. Die
|
meillo@4
|
99 Auswahl aehnelt damit der Mengenlehre in der Mathematik:
|
meillo@4
|
100 Jedes angegebene Feld soll in der Ergebnismenge sein. Die
|
meillo@4
|
101 Felder der Ergebnismenge werden dabei immer in der gleichen
|
meillo@4
|
102 Reihenfolge ausgegeben wie sie in der Eingabe waren.
|
meillo@0
|
103
|
meillo@0
|
104
|
meillo@0
|
105 Geschichtliches
|
meillo@0
|
106
|
meillo@4
|
107 Cut erblickte 1982 mit dem Release von UNIX System III das
|
meillo@4
|
108 Licht der oeffentlichen Welt. Wenn man die Quellen von System
|
meillo@4
|
109 III durchforstet, findet man die Quellcodedatei cut.c mit dem
|
meillo@4
|
110 Zeitstempel 1980-04-11.
|
meillo@1
|
111 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd
|
meillo@4
|
112 Das ist die aelteste Manifestation des Programms, die ich
|
meillo@4
|
113 aufstoebern konnte.
|
meillo@0
|
114
|
meillo@1
|
115 Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein
|
meillo@1
|
116 fruehester Fund ein cut.c mit dem Datum 1986-11-07 im Code der
|
meillo@1
|
117 Spezialversion 4.3BSD-UWisc, die im Januar 1987 veroeffentlicht
|
meillo@4
|
118 wurde.
|
meillo@1
|
119 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
|
meillo@4
|
120 Die Datei unterscheidet sich nur minimal von der aus System III.
|
meillo@4
|
121 Im bekannteren 4.3BSD-Tahoe (1988) taucht cut aber nicht auf.
|
meillo@4
|
122 Im darauf folgenden 4.3BSD-Reno (1990) gibt es wiederum ein
|
meillo@4
|
123 cut ... ein von Adam S. Moskowitz und Marciano Pitargue neu
|
meillo@4
|
124 implementiertes cut, das 1989 in BSD aufgenommen wurde.
|
meillo@1
|
125 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
|
meillo@4
|
126 Seine Manpage
|
meillo@1
|
127 [ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
|
meillo@4
|
128 erwaehnt bereits die erwartete Konformitaet mit POSIX.2.
|
meillo@4
|
129 Nun sollte man wissen, dass POSIX.2 erst im September
|
meillo@4
|
130 1992 veroeffentlicht wurde, gut zwei Jahren *nachdem* die
|
meillo@4
|
131 Manpage und das Programm geschrieben wurden. Dieses cut
|
meillo@4
|
132 wurde also anhand von Entwuerfen des Standards
|
meillo@4
|
133 implementiert. Zweieinhalb Jahre Arbeit war immerhin schon in
|
meillo@4
|
134 den Standardisierungsprozess geflossen; bis zur
|
meillo@4
|
135 Fertigstellung sollte es noch weitere zwei Jahre dauern.
|
meillo@0
|
136
|
meillo@1
|
137 Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut
|
meillo@1
|
138 aus Sicht des urspruenglichen Unix zu den juengeren Tools.
|
meillo@1
|
139 Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist,
|
meillo@4
|
140 so war Unix doch schon ueber zehn Jahre alt, als cut das
|
meillo@4
|
141 erste Mal auftauchte. Insbesondere gehoerte cut noch nicht
|
meillo@4
|
142 zu Version 7 Unix, das die Ausgangsbasis aller modernen
|
meillo@4
|
143 Unix-Systeme darstellt. Die weit komplexeren Programme sed
|
meillo@4
|
144 und awk waren dort schon vertreten. Man muss sich also
|
meillo@4
|
145 fragen, warum cut ueberhaupt noch entwickelt wurde, wo es
|
meillo@4
|
146 schon zwei Programme gab, die die Aufgabe von cut bereits
|
meillo@4
|
147 abdeckten. Ein Argument fuer cut ist seine Kompaktheit und
|
meillo@4
|
148 die damit verbundene Geschwindigkeit gegenueber dem damals
|
meillo@4
|
149 traegen awk. Diese schlanke Gestalt ist es auch, die der Unix
|
meillo@4
|
150 Philosopie entspricht: Mache eine Aufgabe und die richtig!
|
meillo@4
|
151 So bewaehrte sich cut. Es wurde in andere Unix Varianten
|
meillo@4
|
152 uebernommen, standardisiert und ist heutzutage ueberall
|
meillo@1
|
153 anzutreffen.
|
meillo@1
|
154
|
meillo@2
|
155 Mit POSIX.2 im Jahre 1992 wurde cut zum ersten Mal in der
|
meillo@2
|
156 heutigen Form (mit -b) standardisiert. In der urspruenglichen
|
meillo@2
|
157 Variante (ohne -b) taucht es u.a. 1985 in der System V
|
meillo@2
|
158 Interface Definition, einer wichtigen formalen Beschreibung
|
meillo@2
|
159 von UNIX System V, auf.
|
meillo@1
|
160
|
meillo@1
|
161
|
meillo@2
|
162 Beschreibungen
|
meillo@1
|
163
|
meillo@2
|
164 Interessant ist ein Vergleich der Kurzbeschreibungen von cut,
|
meillo@3
|
165 wie sie sich in der Titelzeile von Manpages oder manchmal auch
|
meillo@2
|
166 am Anfang der Quellcodedatei findet.
|
meillo@2
|
167
|
meillo@3
|
168 Die folgende Liste ist grob nach Zeit georndet und nach
|
meillo@3
|
169 Abstammung gruppiert. Die mit ``(src)'' markierten
|
meillo@3
|
170 Beschreibungen wurden im Code gefunden. POSIX und der ``Unix
|
meillo@3
|
171 Reader'' sind Textdokumente, die nicht an eine bestimmte
|
meillo@3
|
172 Unix-Version gebunden sind. Alle uebrigen Beschreibungen
|
meillo@3
|
173 entstammen der jeweiligen Manpage.
|
meillo@3
|
174
|
meillo@3
|
175
|
meillo@2
|
176 System III cut out selected fields of each line of a file
|
meillo@3
|
177 System III (src) cut and paste columns of a table (projection of a relation)
|
meillo@2
|
178 System V cut out selected fields of each line of a file
|
meillo@2
|
179 HP-UX cut out (extract) selected fields of each line of a file
|
meillo@2
|
180
|
meillo@3
|
181 4.3BSD-UWisc (src) cut and paste columns of a table (projection of a relation)
|
meillo@2
|
182 4.3BSD-Reno select portions of each line of a file
|
meillo@2
|
183 NetBSD select portions of each line of a file
|
meillo@2
|
184 FreeBSD 1.0 select portions of each line of a file
|
meillo@3
|
185 FreeBSD 7.0 cut out selected portions of each line of a file
|
meillo@2
|
186 SunOS 4.1.3 remove selected fields from each line of a file
|
meillo@2
|
187 SunOS 5.5.1 cut out selected fields of each line of a file
|
meillo@2
|
188
|
meillo@2
|
189 POSIX cut out selected fields of each line of a file
|
meillo@2
|
190
|
meillo@2
|
191 GNU coreutils remove sections from each line of files
|
meillo@2
|
192
|
meillo@2
|
193 Minix select out columns of a file
|
meillo@2
|
194
|
meillo@2
|
195 Version 8 Unix rearrange columns of data
|
meillo@2
|
196 ``Unix Reader'' rearrange columns of text
|
meillo@2
|
197
|
meillo@2
|
198
|
meillo@2
|
199
|
meillo@3
|
200 Codevergleich
|
meillo@2
|
201
|
meillo@2
|
202
|
meillo@2
|
203
|