Mercurial > docs > cut
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