view cut.txt @ 2:3659d2502d61

Zwischenstand
author markus schnalke <meillo@marmaro.de>
date Sat, 02 May 2015 18:31:00 +0200
parents a3f18ccc3996
children 7cd149433a96
line wrap: on
line source

Das Werkzeugkaestle

#1:  cut - cut out selected fields of each line of a file
---------------------------------------------------------
markus schnalke, 2015-04


Cut ist ein klassisches Programm im Unix-Werkzeugkasten.
In keinem ordentlichen Tutorial zur Shellprogrammierung darf
es fehlen. Es ist ein schoenes Anschauungs- und Beispielobjekt
fuer's Shellscripting. Hier soll es portraitiert werden.


Die Funktionsbasis von cut sind urspruenglich zwei Modi, die
spaeter um einen dritten erweitert wurden. Entweder cut
schneidet bestimmte Zeichen aus den Zeilen der Eingabe oder
bestimmte durch Trennzeichen definierte Felder.

Der Zeichenmodus ist besonders praktisch um bestimmte Teile
von Kommandoausgaben zu extrahieren. Ein populaeres
Beispiel ist die Jahreszahl, die aus einer Datumsangabe
herausgeschnitten werden soll, insofern das Datumsformat
nicht frei gewaehlt werden kann. Ein anderer Anwendungsfall
ist die Extraktion bestimmter Zugriffsrecht. Hier z.B. die
Rechte fuer den Besitzer:

	ls -l foo | cut -c 2-4

Oder die Schreibrechte fuer die Gruppe und alle anderen:

	ls -l | cut -c 6,9

Damit ist die grundsaetzliche Verwendung von cut
demonstriert.

Die fuer POSIX wichtige Funktion von cut ist die Faehigkeit
lange Zeilen zu kuerzen.

	cut -c -80

Dieser Befehl uebernimmt nur die ersten 80 Zeichen der
Eingabe in die Ausgabe. Der Rest der Zeilen wird einfach
abgeschnitten, koennte aber mit `cut -c 81-' extrahiert
werden.

Achtzig Zeichen erinnert unweigerlich an VT100-Terminals,
das 80 Zeichen pro Zeile darstellen kann. Geht es aber nicht
um die Darstellung von Zeichen sondern um ihre Speicherung,
dann ist `-c' nicht unbedingt die passende Option zur Kuerzung
langer Zeilen.

Frueher, als US-ASCII omnipraesente als Zeichensatz und -kodierung
war, war jedes Zeichen durch genau ein Byte kodiert und somit
selektierte `cut -c' sowohl nach Ausgabezeichen als auch nach
Bytes. Mit dem Aufkommen von Multibyte-Kodierungen (wie UTF-8)
musste man sich von dieser Annahme loesen. In diesem Zug
bekam cut mit POSIX.2-1992 die Option `-b'. Diese selektiert
Bytes. Will man also nur die ersten maximal 20 Bytes vor dem
Newline-Zeichen stehen haben (und den Rest stillschweigend
ignorieren), dann macht man das mit:

	cut -b -20


Neben dem Zeichen- bzw. Byte-Modus bietet cut noch den
interessanteren Feld-Modus, den man mit `-f' einleitet. Mit ihm
koennen Felder ausgewaehlt werden. Das Trennzeichen -- per
Default der Tab -- kann mit `-d' geaendert werden.

Der typische Anwendungsfall fuer den Feld-Modus. Ist die
Extraktion von Information aus der passwd-Datei. So z.B. der
Username, die User-ID und das Homeverzeichnis:

	cut -d: -f1,3,6 /etc/passwd

(Die Argumente fuer die Optionen koennen bei cut uebrigens
direkt angehaengt oder mit Whitespace abgetrennt folgen.)


Dieser Feld-Modus ist fuer einfache tabellarische Dateien
(wie eben die passwd) gut geeignet, kommt aber schnell an
seine Grenzen. Gerade der uebliche Fall, dass an Whitespace
in Felder geteilt werden soll, wird damit nicht abgedeckt.
Der Delimiter kann nur genau ein Zeichen sein. Es kann also
nicht sowohl an Leerzeichen als auch an Tabs getrennt werden.
Auch unterteilt cut an jedem Trennzeichen. Zwei aneinander
stehende Trennzeichen fuehren zu einem leeren Feld. Solches
Verhalten ist fuer Whitespace-getrennte Felder unangemessen.
Diese Aufgaben deckt aber zum Glueck awk ab, so dass die
Alternative zur Hand ist.

Awk hat eine weitere Funktion, die
cut missen laesst: Das Tauschen der Feld-Reihenfolge.





Geschichtliches

Cut erblickte 1982 als Teil von UNIX System III das Licht der
oeffentlichen Welt. In den Quellen von System III findet sich
cut.c mit dem Zeitstempel 1980-04-11.
[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=SysIII/usr/src/cmd

Aber werfen wir doch einen Blick auf die BSD-Linie: Dort ist mein
fruehester Fund ein cut.c mit dem Datum 1986-11-07 im Code der
Spezialversion 4.3BSD-UWisc, die im Januar 1987 veroeffentlicht
.
[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-UWisc/src/usr.bin/cut
Im bekannteren 4.3BSD-Tahoe (1988) taucht es nicht auf. Im
darauf folgenden 4.3BSD-Reno (1990) gibt es aber wiederum ein
cut, das von Adam S. Moskowitz und Marciano Pitargue geschrieben
und 1989 in BSD aufgenommen worden ist.
[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut
Die Manpage
[ http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.3BSD-Reno/src/usr.bin/cut/cut.1
erwaehnt bereits die angestrebte aber noch vermutete Konformitaet
zu POSIX.2. Man muss wissen, dass POSIX.2 erst im September
1992 veroeffentlicht wurde. Die Aussage basiert also auf dem
Zwischenstand nach zweieinhalb der insgesamt fuenf Jahre, die
die Arbeiten am Standard benoetigten.

Trotz all dieser Jahreszahlen aus den 80er Jahren gehoert cut
aus Sicht des urspruenglichen Unix zu den juengeren Tools.
Wenn cut auch ein Jahrzehnt aelter als Linux, der Kernel, ist,
so existierte Unix wiederum schon ein ganzes Jahrzehnt bevor cut
das erste Mal auftauchte. Insbesondere war cut nicht in Version 7
Unix vorhanden, das die Ausgangsbasis aller modernen Unix-Systeme
darstellt. (Das weit komplexere sed z.B. war dort schon
vertreten.)

Nichts desto trotz bewaehrte sich cut. Es wurde in andere
Unix Varianten uebernommen und ist heutzutage ueberall
anzutreffen.

Mit POSIX.2 im Jahre 1992 wurde cut zum ersten Mal in der
heutigen Form (mit -b) standardisiert. In der urspruenglichen
Variante (ohne -b) taucht es u.a. 1985 in der System V
Interface Definition, einer wichtigen formalen Beschreibung
von UNIX System V, auf.


Beschreibungen

Interessant ist ein Vergleich der Kurzbeschreibungen von cut,
wie man sie in der Titelzeile der Manpages oder manchmal auch
am Anfang der Quellcodedatei findet.

System III	cut out selected fields of each line of a file
System III code	cut and paste columns of a table (projection of a relation)
System V	cut out selected fields of each line of a file
SVID		cut out selected fields of each line of a file
HP-UX		cut out (extract) selected fields of each line of a file

4.3BSD-UWisc	cut and paste columns of a table (projection of a relation)
4.3BSD-Reno	select portions of each line of a file
NetBSD		select portions of each line of a file
FreeBSD 1.0	select portions of each line of a file
FreeBSD >2007	cut out selected portions of each line of a file
SunOS 4.1.3	remove selected fields from each line of a file
SunOS 5.5.1	cut out selected fields of each line of a file

POSIX		cut out selected fields of each line of a file

GNU coreutils	remove sections from each line of files

Minix		select out columns of a file

Version 8 Unix	rearrange columns of data
``Unix Reader''	rearrange columns of text