klicken - Centrum für Informations- und Sprachverarbeitung

Transcription

klicken - Centrum für Informations- und Sprachverarbeitung
Einführung in die Programmierung für
Computerlinguisten
Centrum für Informations- und Sprachverarbeitung, LMU München
Dr. Maximilian Hadersbeck
Mitarbeiter an der Erstellung des Skripts:
Dokumentvorlage und LATEX-Spezialist: Daniel Bruder
Konvertierung des Skripts nach LATEX: Ekaterina Peters
Mitarbeit: Claudia Müller, Junhan Chen, Stefan Schätz, Nicola Greth
— Version Wintersemester 2015/2016 —
Inhaltsverzeichnis
1. Geschichte und Aufgaben der Informatik
1.1. Rechner der nullten Generation . . . . . . . . . . .
1.2. Rechner der ersten Generation 1946 – 1965 . . . .
1.3. Die Rechner der zweiten Generation 1957 – 1963 .
1.4. Rechner der dritten Generation 1964 – 1981 . . . .
1.5. Die Rechner der vierten Generation 1982-1989 . . .
1.6. Die Rechner der fünften Generation . . . . . . . .
1.7. Die Rechnergenerationen bis ca. 1990 im Überblick
1.8. Verwendete Abkürzungen . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
. 2
. 3
. 4
. 5
. 7
. 7
. 8
. 10
2. Die Programmiersprache Perl
2.1. Allgemeines zu Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2. Kurzübersicht zu Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3. Aufbau eines Perl Programms . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1. Das erste Perl-Programm . . . . . . . . . . . . . . . . . . . . . . . .
2.4. Start eines Perl Programms . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.5. Editieren und Starten eines Perl - Programms mit dem UNIX Programm kate
2.5.1. Bemerkungen zur Syntax von Perl Programmen . . . . . . . . . . .
2.6. Datenstrukturen 1: Skalare und Listen . . . . . . . . . . . . . . . . . . . . .
2.6.1. Vorbemerkung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.6.2. Einfache Datenstrukturen: Skalare . . . . . . . . . . . . . . . . . . .
2.6.3. Zusammengesetzte Datenstrukturen: Listen . . . . . . . . . . . . . .
2.7. Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.7.1. Deklaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8. Ausdrücke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8.1. Wertzuweisung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.8.1.1. Zuweisung einer Konstanten . . . . . . . . . . . . . . . . .
2.8.1.2. Zuweisung eines Ausdrucks . . . . . . . . . . . . . . . . . .
2.8.2. Einlesen der Daten vom Terminal . . . . . . . . . . . . . . . . . . . .
2.9. Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.1. arithmetische Operatoren . . . . . . . . . . . . . . . . . . . . . . . .
2.9.2. string Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.9.3. Grundlagen: Logische Ausdrücke . . . . . . . . . . . . . . . . . . . .
2.9.4. Vergleichsoperatoren . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10. Kontrollstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.1. Blöcke . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.2. Auswahlanweisung: if . . . . . . . . . . . . . . . . . . . . . . . . . .
2.10.3. Auswahlanweisung: if...else . . . . . . . . . . . . . . . . . . . . . . .
2.10.4. Wiederholungsanweisung: while . . . . . . . . . . . . . . . . . . . . .
2.10.5. Wiederholungsanweisung: do while . . . . . . . . . . . . . . . . . . .
2.10.6. Wiederholungsanweisung: do...until . . . . . . . . . . . . . . . . . . .
2.10.7. Wiederholungsanweisung: foreach . . . . . . . . . . . . . . . . . . . .
2.10.8. Wiederholungsanweisung: for . . . . . . . . . . . . . . . . . . . . . .
11
11
11
12
12
13
13
14
15
15
15
15
16
17
18
19
19
19
20
23
23
23
23
24
27
27
28
28
29
31
31
32
32
i
ii
Inhaltsverzeichnis
2.11. Lesen von Daten aus einer Datei . . . . . . . . . . . . . . . . . . . . . . .
2.11.1. Dateihandles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.12. Interne Repräsentation von Zahlen . . . . . . . . . . . . . . . . . . . . . .
2.13. Interne Repräsentation von Schriftzeichen . . . . . . . . . . . . . . . . . .
2.13.1. Speicherung von Strings . . . . . . . . . . . . . . . . . . . . . . . .
2.13.2. Speicherung von Buchstaben . . . . . . . . . . . . . . . . . . . . .
2.13.3. Zeichencodierung: ASCII, für Buchstaben, mit 7 Bit . . . . . . . .
2.13.4. Bedeutung der Steuerzeichen . . . . . . . . . . . . . . . . . . . . .
2.13.5. Zeichencodierung: ISO Latin-1 für Buchstaben, 8 Bit . . . . . . . .
2.13.6. Zeichenkodierung nach den Vorgaben des UNICODE Konsortium .
2.13.7. Die UTF Prinzipien . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.8. Die UTF Kodierung im Detail . . . . . . . . . . . . . . . . . . . .
2.13.9. UTF-8 im Internet . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.13.10.UTF-8 Mode in Perl . . . . . . . . . . . . . . . . . . . . . . . . . .
2.14. Lesen der Daten vom Terminal mit utf8 Kodierung . . . . . . . . . . . . .
2.14.1. Standardein- und ausgabe beim Programmstart auf utf8 festlegen
2.14.2. Standardein- und ausgabe zur Laufzeit auf utf8 festlegen . . . . .
2.14.3. Lesen aus Dateien mit utf-8 Kodierung . . . . . . . . . . . . . . . .
2.15. Die spezielle Variable : $_ . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16. Datenstrukturen 2: Hashes . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.1. Hash Operatoren . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.2. Löschen von Einträgen im Hash . . . . . . . . . . . . . . . . . . . .
2.16.3. Zugriff auf den Hash . . . . . . . . . . . . . . . . . . . . . . . . . .
2.16.3.1. Zugriff auf alle Keys im Hash . . . . . . . . . . . . . . . .
2.16.3.2. Zugriff auf alle Werte im Hash . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
33
34
36
38
38
38
39
39
40
43
44
44
46
46
48
49
49
50
51
53
54
54
54
54
54
57
57
57
58
58
58
59
59
59
59
60
60
60
61
62
63
63
3. Reguläre Ausdrücke in Perl
3.1. Buchstaben in einem regulären Ausdruck . . . . . . . . . .
3.2. Übersicht über Metazeichen . . . . . . . . . . . . . . . . . .
3.3. Metazeichen . = Wildcard . . . . . . . . . . . . . . . . . . .
3.4. Metazeichen [ ] = Buchstabenbereiche . . . . . . . . . . . .
3.5. Metazeichen * , + , ? { } = Quantifizierung . . . . . . . . .
3.6. Metazeichen ( ) = Zeichengruppierung . . . . . . . . . . . .
3.7. Metazeichen ˆ = Anfang der Zeile . . . . . . . . . . . . . .
3.8. Metazeichen $ = Ende der Zeile . . . . . . . . . . . . . . . .
3.9. Metazeichen \= Ausschalten der Metazeichenerkennung . .
3.10. Metazeichen [ˆ ] = negierte Buchstabenbereiche . . . . . . .
3.11. Buchstabenklassen ohne UNICODE . . . . . . . . . . . . .
3.12. Buchstabenklassen mit UNICODE . . . . . . . . . . . . . .
3.13. Zugriff auf gruppierte Teile des Regulären Ausdrucks . . . .
3.14. Globales Suchen in einer Zeile . . . . . . . . . . . . . . . . .
3.15. Ersetzen von Strings: substitute . . . . . . . . . . . . . . . .
3.16. Greedy-Nongreedy Verhalten bei Quantifizierung . . . . . .
3.17. Zugriff auf gruppierte Teile des regulären Ausdrucks beim
Zeichenketten . . . . . . . . . . . . . . . . . . . . . . . . . .
3.18. Suchen über Zeilengrenzen hinweg . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
Ersetzen von
. . . . . . . .
. . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4. Systemroutinen in Perl
4.1. Vorbemerkung .
4.2. split . . . . . .
4.3. ord . . . . . . . .
4.4. chr . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 64
. 64
66
66
66
67
68
Inhaltsverzeichnis
4.5. length .
4.6. scalar .
4.7. join . .
4.8. pop . . .
4.9. push . .
4.10. shift .
4.11. unshift
4.12. reverse
4.13. sort . .
iii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
68
68
69
69
70
70
71
71
72
5. Subroutinen in Perl
5.1. Definition von Subroutinen in Perl . . . . . . . . . . . . . . . . . . . . . . .
5.2. Datenaustausch zwischen Subroutinen und Hautpprogramm . . . . . . . . .
5.3. Zugriff auf die Argumentvariablen in Subroutinen . . . . . . . . . . . . . . .
5.3.1. Lokale Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3.2. Gültigkeitsbereich von lokalen Variablen . . . . . . . . . . . . . . . .
5.3.3. Übergabe des Argumentwerts an eine lokale Variable in der Subroutine
5.4. Probleme bei der Übergabe von Argumenten an eine Subroutine . . . . . .
5.4.1. Übergabe der Argumentvariable als Referenz: . . . . . . . . . . . . .
5.4.2. Übergabe der Argumentvariablen als Referenz und Ändern des Wertes der Argumentvariable: . . . . . . . . . . . . . . . . . . . . . . . .
5.5. Rückgabewerte von Subroutinen . . . . . . . . . . . . . . . . . . . . . . . .
5.6. Globale Variablen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.6.1. Die Verwendung von our . . . . . . . . . . . . . . . . . . . . . . . . .
5.7. Rekursion bei Subroutinen . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.8. Exkurs: Übergabemechanismus in Perl im Detail (für den Spezialisten) : . .
5.8.1. Der STACK Speicher bei Subroutinenaufrufen . . . . . . . . . . . .
5.9. Beispiel: Berechnung des Wochentags in Abhängikeit vom Datum . . . . . .
81
81
82
82
82
83
84
85
6. Aufgaben und Lösungen
6.1. Aufgabe: größte/kleinste Zahl . . . . . . . . .
6.2. Aufgabe: Alphabetischer Vergleich . . . . . .
6.3. Aufgabe: Fakultät (iterativ, rekursiv) . . . . .
6.4. Aufgabe: Einlesen einer Rechenaufgabe . . . .
6.5. Aufgabe: Wörter mit Selbstlauten extrahieren
6.6. Aufgabe: Buchstaben zählen . . . . . . . . . .
6.7. Aufgabe: Passwort abfragen . . . . . . . . . .
6.8. Aufgabe: Wörter mit drei Buchstaben . . . .
6.9. Aufgabe: Wörter zählen . . . . . . . . . . . .
6.10. Aufgabe: Split von Zeilen und Wortliste . . .
6.11. Aufgabe: Frequenzliste . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
89
89
89
90
91
92
92
93
94
94
95
96
.
.
.
.
.
.
.
.
97
97
97
97
98
98
99
99
99
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
7. Linux
7.1. Einführung in Linux . . . . . . . . . . . . . . . . . . . . .
7.1.1. Einleitung . . . . . . . . . . . . . . . . . . . . . . .
7.1.2. Eigenschaften . . . . . . . . . . . . . . . . . . . . .
7.2. Verwalten von Dateien Teil 1 . . . . . . . . . . . . . . . .
7.2.1. Einleitung . . . . . . . . . . . . . . . . . . . . . . .
7.2.2. Das Linux Dateisystem . . . . . . . . . . . . . . .
7.2.2.1. Der hierarchische Dateibaum . . . . . . .
7.2.2.2. Verzeichnisse, Dateien und Gerätedateien
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
73
73
74
75
76
77
77
78
79
iv
Inhaltsverzeichnis
7.3.
7.4.
7.5.
7.6.
7.2.3. Fallbeispiel zum Verwalten von Dateien . . . . . . . . . . . . . . .
7.2.3.1. Das Anlegen von Dateien . . . . . . . . . . . . . . . . . .
7.2.3.2. Das Anzeigen von Inhaltsverzeichnissen . . . . . . . . . .
7.2.3.3. Länge und Zeichenkonventionen von Dateinamen . . . . .
7.2.3.4. Das Löschen von Dateien . . . . . . . . . . . . . . . . . .
7.2.3.5. Das Anzeigen von Dateien . . . . . . . . . . . . . . . . .
7.2.3.6. Das Verwalten von Verzeichnissen . . . . . . . . . . . . .
7.2.3.7. Das Kopieren und Umbenennen von Dateien . . . . . . .
7.2.4. Dateinamen und der Einsatz von Wildcards . . . . . . . . . . . . .
7.2.4.1. Einsatz von Wildcards . . . . . . . . . . . . . . . . . . . .
7.2.4.2. Verwendung von Sonderzeichen . . . . . . . . . . . . . . .
7.2.5. Das Wichtigste in Kürze . . . . . . . . . . . . . . . . . . . . . . . .
7.2.6. Tipps für die Praxis . . . . . . . . . . . . . . . . . . . . . . . . . .
Editieren von Texten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.1. Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.2. Aufrufen des kate Editors . . . . . . . . . . . . . . . . . . . . . . .
7.3.2.1. Sitzungen: . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3.2.2. Erstellen einer neuen Datei . . . . . . . . . . . . . . . . .
7.3.2.3. Die Fenster des kate Editors . . . . . . . . . . . . . . . .
7.3.3. Wichtige Menüeinträge . . . . . . . . . . . . . . . . . . . . . . . .
7.3.4. Spezielle Kommandos zum praktischen Gebrauch . . . . . . . . . .
7.3.5. Andere Editoren . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Verwaltung von Dateien Teil 2 . . . . . . . . . . . . . . . . . . . . . . . .
7.4.1. Die einzelnen Merkmale einer Datei . . . . . . . . . . . . . . . . .
7.4.1.1. Die Dateimerkmale im Überblick . . . . . . . . . . . . . .
7.4.2. Gruppen und Owner . . . . . . . . . . . . . . . . . . . . . . . . . .
7.4.2.1. Zugriffsrechte unter Linux . . . . . . . . . . . . . . . . . .
7.4.3. Die Bedeutung von Devicegrenzen . . . . . . . . . . . . . . . . . .
7.4.3.1. Plattenplatzbelegung . . . . . . . . . . . . . . . . . . . .
7.4.3.2. Der Symbolic Link . . . . . . . . . . . . . . . . . . . . . .
7.4.4. Das Wichtigste in Kürze . . . . . . . . . . . . . . . . . . . . . . . .
UNIX-Befehle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.1. Hilfe (Befehlsoptionen, Parameter, generelle Verwendungsweise, Verwendungsbeispiele) . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.2. Einsatz der UNIX-Shell: Pipes, >, < (Ausgabeumleitung) . . . . .
7.5.3. Kommandooptionen . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.4. Shells: bash, tcsh . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.5. Was ist los auf dem Rechner? . . . . . . . . . . . . . . . . . . . . .
7.5.6. Wegwerfen der Ausgabe einer Datei . . . . . . . . . . . . . . . . .
7.5.7. Archive anlegen . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.8. Komprimieren von Dateien . . . . . . . . . . . . . . . . . . . . . .
7.5.9. Archivieren mit Komprimieren . . . . . . . . . . . . . . . . . . . .
7.5.10. Finden von Dateien und ausführen eines Befehls . . . . . . . . . .
7.5.11. Finden von Unterschieden in Dateien . . . . . . . . . . . . . . . . .
7.5.12. UNIX: Tokenisierung, Sortieren, Frequenzlisten . . . . . . . . . . .
7.5.13. Translate von Zeichen . . . . . . . . . . . . . . . . . . . . . . . . .
7.5.14. Sortieren-einer-wortliste . . . . . . . . . . . . . . . . . . . . . . . .
7.5.15. Report und Unterdrücken von Zeilen . . . . . . . . . . . . . . . . .
7.5.16. Erzeugen einer Wortliste . . . . . . . . . . . . . . . . . . . . . . . .
Automatisieren von Befehlsfolgen mit der Shell . . . . . . . . . . . . . . .
7.6.1. Was ist ein Shellscript . . . . . . . . . . . . . . . . . . . . . . . . .
7.6.2. Benutzung von Shellscripts . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
100
100
101
101
101
102
102
103
103
103
104
104
105
105
105
106
107
107
108
109
110
110
111
111
111
111
112
114
114
114
114
115
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
115
116
116
116
116
117
117
117
117
117
118
118
118
118
119
119
120
120
120
Inhaltsverzeichnis
7.6.3. Das Wichtigste in Kürze . . . . . . . . . . . . . . . .
7.7. Drucken . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.7.1. CUPS . . . . . . . . . . . . . . . . . . . . . . . . . .
7.7.1.1. Druckaufträge erzeugen (klassisch) . . . . .
7.7.1.2. Das Anzeigen von Druckjobs . . . . . . . .
7.7.1.3. Das Löschen von Druckjobs . . . . . . . . .
7.7.1.4. Das Wichtigste in Kürze . . . . . . . . . .
7.8. Linux-Befehle – eine kurze Übersicht . . . . . . . . . . . . .
7.8.1. Dokumentation, Dateien, Pfade . . . . . . . . . . . .
7.8.2. Textverarbeitung . . . . . . . . . . . . . . . . . . . .
7.8.3. Komprimieren von Dateien/ Ordnern . . . . . . . .
7.8.4. Dateisystem . . . . . . . . . . . . . . . . . . . . . . .
7.8.5. Prozessmanagement und User . . . . . . . . . . . . .
7.8.6. Zeichensätze . . . . . . . . . . . . . . . . . . . . . .
7.8.7. Umgebungsvariablen . . . . . . . . . . . . . . . . . .
7.8.8. Netzwerkeigenschaften . . . . . . . . . . . . . . . . .
7.8.9. Via Internet Dateien kopieren/ Rechner fernsteuern
7.8.10. Operatoren zur Ausgabe-/Eingabeumleitung . . . .
7.8.11. Versionsverwaltung . . . . . . . . . . . . . . . . . . .
7.8.12. Sonstiges . . . . . . . . . . . . . . . . . . . . . . . .
v
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
120
121
121
121
121
121
121
122
122
123
124
124
125
126
126
126
127
127
127
128
Literaturverzeichnis
129
Abbildungsverzeichnis
130
Tabellenverzeichnis
131
A. Anhang
132
A.1. Die Backus-Naur-Form (BNF) . . . . . . . . . . . . . . . . . . . . . . . . . . 132
1. Geschichte und Aufgaben der Informatik
Der Name Informatik besteht aus zwei Teilen:
• Information
• Mathematik siehe im Buch von Herbert Klären (Kla90)
Die Informatik beschäftigt sich mit
• Informationssystemen:
Struktur, Wirkungsweisen, Fähigkeiten und Konstruktionsprinzipien
• Modellen und Simulation
• Möglichkeiten der Strukturierung, Formalisierung und Mathematisierung von Anwendungsgebieten
Um für diese Bereiche Computerprogramme anbieten zu können, erforscht die Informatik:
• abstrakte Zeichen, Objekte und Begriffe
• formale Strukturen und ihre Transformation nach formalen Regeln
• die effektive Darstellung solcher Strukturen im Rechner und der automatischen
Durchführung der Transformationen.
Anwendungen der Informatik finden wir unter anderem in folgenden Bereichen:
• Handel
• Industrie
• Wissenschaft
• Ingenieurwesen
• Sozialwissenschaft
• Medizin
• Ausbildung
• Kunst
• Freizeit
Eine sehr gute Einführung in die Informatik findet sich im Buch (H.-94)
1
2
1. Geschichte und Aufgaben der Informatik
1.1. Rechner der nullten Generation
• 1623 – 1624: Wilhelm Schickard
Ein Universalgenie konstruiert die wohl erste Rechenmaschine. Auf sein Konto geht
das Konstruktionsprinzip von Ziffernrädern und Zehnerübertragung.
• 1642: Blaise PASCAL
führt in Paris eine Maschine vor, die addieren und auf Umwegen auch subtrahieren
kann. Sie hatte zehnstufige Zahnräder, der Zehnerübertrag wurde durch eine Klaue
und Mitnehmerstifte realisiert.
• 1673: Gottfried Leibnitz
stellt in London seine Replica vor, die alle 4 Grundrechenarten mit 12-stelliger Anzeige
bewältigen kann. Er erfindet außerdem das Dualsystem.
• 1822: Charles Babbage
Er entwickelt das Konzept der difference engines zur Überprüfung von Logarithmentafeln. Doch war es damals nicht möglich, ein mechanisches Getriebe zu bauen, bei
dem 25 Zahnräder ineinandergreifen können, ohne zu verklemmen. 1833 entwarf er
das Konzept der analytical engine, der ersten digitalen Rechenanlage. Sie enthielt
schon sämtliche Komponenten einer modernen Rechenanlage:
– arithmetischer Zahlenspeicher
– arithmetische Recheneinheit
– Steuereinheit zur Steuerung des Programmablaufs einschließlich der Rechenoperationen und des Datentransports
– Geräte für Ein-/Ausgabe
– dekadische Zahnräder für die Rechnung
– zur Steuerung: Lochkarten
– logische Verzweigungen und Entscheidungen
– Die Addition sollte 1 sek., die Multiplikation zweier 50-stelliger Zahlen 1 Minute
dauern.
Zu Lebzeiten bezeichnete man ihn als Narren und keiner verstand ihn. Seine Frau
Augusta Ada veröffentlichte seine Arbeiten und sein Sohn versuchte Teile dieser
Maschine zu bauen, die heute noch im Science-Museum zu London zu besichtigen
sind.
• 1847: George Boole
Er entwickelt einen Formalismus für die mathematische Behandlung von verschiedenen
Aussageverknüpfungen, die mit den beiden Begriffen „wahr“ und „falsch“ arbeiten.
Heute spricht man von der Bool´schen Algebra.
• 1938: Konrad Zuse
entwickelt ein Rechnerkonzept mit den logischen Grundoperationen. Er schlug einen
programmgesteuerten Rechenautomaten mit 1500 Elektronenröhren vor. Die deutsche
Regierung beurteilte eine solche Entwicklung als völlig sinnlos. Im Auftrag der
deutschen Luftfahrtindustrie entsteht 1941 die Z3, ein Rechner mit 600 Relais im
Rechenwerk und 2000 Relais im Speicherwerk. In den USA wurde parallel dazu 1944
völlig unabhängig von Prof. H. Aiken, Professor für angewandte Mathematik an der
Harvard University den Rechner MARK 1 entwickelt. Er bestand aus:
– 17 Gestellen mit Motoren und Drehschaltern
1.2. Rechner der ersten Generation 1946 – 1965
3
– 3000 Kugellagern
– 800 km Leitungsdraht
– 760.000 Einzelteilen
Eine Multiplikation benötigte 6 Sekunden (sie wurde in der NAVY für die Errechnung
von Funktionstabellen verwendet).
• 1945: John v. Neumann
entwickelt in einer genialen Abstraktion des Steuerungsprozesses folgendes Programmierschema: Das steuernde Programm wird als Information codiert und in den
Informationsspeicher des Rechners mit eingelagert.
– Programmsprünge innerhalb des Programms möglich
– Steigerung der Rechengeschwindigkeit
Erst 1949 wurde dieses Konzept zum ersten Mal angewendet.
Beispiel: Strickmaschine
Fest eingestelltes Programm: Start → Ergebnis (keine Sprünge)
Bei Neumann: Programm + Daten, Programm wird codiert → Sprünge sind
erforderlich.
Arbeitsweise der Rechner der 0. Generation
Anweisungen, also Programme von außen mittels Lochkarten, Lochstreifen oder Programmstecktafeln.
Programmverzweigungen, Schleifen und Unterprogramme nur mit Spezialeinrichtungen
wie zusätzlichen Programmstreifenleser und Endlosschleifen möglich.
1.2. Rechner der ersten Generation 1946 – 1965
• 1946: wurde an der Universität von Pennsylvania der erste Röhrenrechner entwickelt
→ENIAC Electronic Numerical Integrator And Computer.
– 18.000 Röhren
– 1500 Relais
– 70.000 Widerstände
– 10.000 Kondensatoren
– mehr als eine halbe Million Lötstellen
– 30 Tonnen Gewicht
– Addition 0.2 · 10−3 Sekunden
– Multiplikation 2.8 · 10−3 Sekunden.
– Leistungsverbrauch 150 KW
– Rechensystem dezimal.
Wurde für die Lösung von Differentialgleichungen am Ballistic Research Labor eingesetzt. Der Rechner war sehr zuverlässig, da die Röhren nur mit 25% ihrer Leistungsfähigkeit betrieben wurden. Die Ausfallrate betrug 2 - 3 Röhren pro Woche.
• 1951: wurde das UNIVAC (Universal-Automatic Computer)-System entwickelt:
– Röhrenrechner
– gemischtes Dual-Dezimal-System
4
1. Geschichte und Aufgaben der Informatik
– Addition 120 ms
– Multiplikation 1.8 ms
– Division 3.6 ms
Von der UNIVAC wurden insgesamt 45 Systeme hergestellt.
Der Rechner bestand aus:
– 5000 Röhren
– 18.000 Dioden
– 300 Relais
– Als Speicher wurden Quecksilber-Verzögerungsleitungen (höchst giftig) verwendet.
• 1952: entwickelt IBM einen legendären Rechner mit der Bezeichnung 701
Die Leistungsmerkmale sind:
– sehr schnell, ebenfalls Röhrenrechner
– als Hintergrundspeicher: Magnetband aus Kunststoff (bisher Metall-Magnetband).
• 1957: Entwicklung der Programiersprache FORTRAN (Formula Translation)
Das Einsatzgebiet der Programmiersprache war im Numerischen Bereich der Mathematik. Der Leiter der Forschungsgruppe, die FORTRAN entwickelte, war John
Backus.
Anlagenstruktur der Rechner der ersten Generation:
Die Rechner arbeiten im Blockzeitbetrieb.
Das Programm arbeitet mit einem Operator zusammen, der Schalter umlegen muss.
Dadurch arbeitet das Programm direkt mit der Befehlsschnittstelle. E/A-Geräte werden
ebenfalls vom Rechner bedient. Dadurch sehr langsamer Durchsatz.
1.3. Die Rechner der zweiten Generation 1957 – 1963
In dieser Rechnergeneration wurde folgendes entwickelt bzw. eingesetzt:
- Entwicklung der Transistortechnik
- Rechner arbeiten mit Binärsystem
- Magnetspeicher
• 1956: IBM führt den Rechner 305 ein (CDC 66000).
• 1956: Entwicklung der IC-Technik (integrated circuit) bei Texas Instruments
Bei einem IC wird auf photomechanischem Weg in einem kleinen Halbleiterstück die
elekronische Wirkung von Transistoren, elektrischen Widerständen und Kondensatoren erreicht. Die Anzahl der simulierten Bausteine resultiert aus der sogenannten
Packungsdichte der Transistoren.
• 1958: Entwicklung der Programmiersprache LISP von John McCarthy
• 1959: Die Programmiersprache COBOL (Common Business Oriented Language)
wird entwickelt.
1.4. Rechner der dritten Generation 1964 – 1981
5
• 1960: In Europa wird die erste blockstrukturierte Programmiersprache ALGOL 60
(Algorithmic Language) von führenden Wissenschaftlern der Welt auf mehreren
Tagungen entwickelt! (unter Beteiligung von Prof. Bauer, TU München)
Anlagenstruktur der Rechner der zweiten Generation:
- Stapelbetrieb mit Vorrechnern
- Programme werden als Stapel eingegeben
- Langsame Peripherie auf Vorrechner
- Compiler, Bibliothek auf MB (Operator muss nur noch Schalter auf MB umlegen)
1.4. Rechner der dritten Generation 1964 – 1981
In dieser Rechnergeneration wurde folgendes entwickelt bzw. eingesetzt:
• IC-Technik
• Microprozessoren, 8 und 16 Bit
• Schnelle Speicher
Microprozessoren erweitern die bisherige Funktionalität eines ICs um folgende Komponenten, die auf photomechanischem Weg in einen Halbleiterbaustein eingebrannt werden.
Microprozessoren bestehen aus folgenden Komponenten:
• Steuerwerk
• Rechenwerk
• Befehlszeilen
• Akkumulator
• Befehlsregister
• Register
Die einzelnen Komponenten konnten Binärzahlen verarbeiten. Die Wortlänge der Binärzahlen war in den ersten Microprozessoren 4 Bit.
• 1962: Weiterentwicklung von FORTRAN zu FORTRAN IV
• 1965: erster Prozessorrechner von DEC PDP8: Minicomputer, kostete weniger als
20.000$. Die Anzahl der Transistoren pro Chip nahm zu.
• 1968: Es entsteht ALGOL 68 und eine ANSI Spezifikation von COBOL Common
Business Oriented Language. COBOL wird in der Betriebswirtschaft und dem
Bankwesen eingesetzt, da COBOL sehr gute kaufmännische Routinen zur Verfügung
stellt.
• 1970: Erfindung des Mikroprozessors von Intel 1103 (4bit)
Es beginnt die Arbeit an PROLOG = programming in logic.
Weiterentwicklung von LISP.
PASCAL wird von Niklaus Wirth erfunden
6
1. Geschichte und Aufgaben der Informatik
• 1971: Der erste General-Purpose Microprocessor wird von der Firma Intel entwickelt:
Intel 4004, 4 Bit, 108 kHz Taktung, Geschwindigkeit: 0,06 MIPS, enthält 2300
Transistoren. Der Chip wurde im Auftrag der japanischen Firma Busicom entwickelt
und von der Firma Intel für $60000 zurückgekauft.
• 1972: Epoche der Großintegration LSI: Large Scale Integration (mehrere tausend
Transistoren auf einem Chip), Dennis Ritchie entwickelt die Programmiersprache
C
• 1974: Intel entwickelt den ersten 8 Bit Chip, den 8080. Er wurde als erster CHIP
weitverbreitet in Ampelsteuerungen eingesetzt.
• 1975: Tiny BASIC wird definiert und auf einem Microcomputer mit 2 KB RAM
von Bill Gates und Paul Allen zum Einsatz gebracht. Die Entwicklung von Kleinrechnern beginnt, als komplette Leiterplatinen entwickelt wurden auf denen
- ICs
- Mikroprozessoren
- Datenspeicher
aufgelötet waren. Durch die Erweiterung der Platinen um Peripherie, Stromversorgung, Terminal, Keyboard und Gehäuse konnte man nun Kleincomputer selbst
zusammenstellen.
• 1976: Der 24-jährige Steve Jobs und der 20-jährige Steve Wosniak gründen ein
Unternehmen und bauen um den Microprozessor 6502 den ersten Kleinrechner.
Sie vervollständigen die Kits um Peripherie (Tastatur, Bildschirm) und schreiben
zugehörige Software. Sie nennen die Firma „Apple“.
Die Packungsdichte der Transistoren vergrößert sich:
• 1977: 16K-Speicher werden entwickelt.
Die Chips haben 20.000 Transistoren auf einem Baustein.
• 1978: Der zweite 8-bit-Microprozessor INTEL 8086, der Start der erfolgreichen x86
Architektur, wird entwickelt.
Einführung des ZILOG Z80 mit dem berühmten Betriebssystem CP/M
Erste optische Datenspeicher werden vorgestellt (Phillips)
• 1979: Höchstintegration auf Chips (VLSI: Very Large Scale Integration, d.h. mehr
als 100.000 Transistoren auf einer Fläche von 20 x 40 mm2 )
- neue Transistormaterialien: Galliumarsenid
- schnelle Schalter: Josephson Schalter mit einer Schaltzeit von 13 · 10−12 sec.,
allerdings nur bei einer Temperatur von -269°C
- große Speicherbausteine
- 2-Mbit-Speicher (Bubble-Speicher). Als schnelle Hintergrundspeicher werden
Plattenlaufwerke entwickelt. Programmiersprachen: PASCAL, LISP
Anlagenstruktur der Rechner der dritten Generation:
Kleinrechner und Timesharingsysteme mit Bildschirm und Tastatur.
1.5. Die Rechner der vierten Generation 1982-1989
7
1.5. Die Rechner der vierten Generation 1982-1989
In dieser Rechnergeneration wurde folgendes entwickelt bzw. eingesetzt:
- 32-bit-Mikroprozessoren (160.000 Transistoren)
- 128k große Speicher auf einem Chip.
- Computer werden über Netzwerke verbunden. Damit beginnt das Zeitalter des
Distributed Processing.
• 1983: Die Programmiersprache Smalltalk-80 wird implementiert.
Die Programmiersprache ADA entsteht im Auftrag des DoD.
ADA war der Versuch des Amerikanischen Verteidigungsministerium, eine Programmiersprache einzuführen, die als Standard für alle militärischen Entwicklungen
verwendet werden sollte.
Ein Microprocessor mit sehr guten I/O Möglichkeiten, der MOTOROLA 68000,
wird entwickelt. Mit diesem Processor können die Graphische Oberflächen leicht
programmiert werden. Er wird zum ersten Mal im Rechner APPLE LISA von Steve
Woszniak und Steve Jobs eingesetzt.
• 1985: INTEL entwickelt den 80386 Processor
• 1986: Es entstehen TURBO PASCAL, Eiffel. C++ wurde von Bjarne Stroustrup
entwickelt und war eine Weiterentwicklung von „C“, d.h. Abwärtskompatibilität zu
C war vorhanden. Dazu kam das objektorientierte Konzept (programmierabhängige
Definition von Objekten)
Die Firma MIPS entwickelt den ersten RISC Prozessor R2000
• 1985: Die Firma SUN entwickelt ihre RISC SPARC Architektur.
• 1988: Es entsteht COMMON LISP und von Nikolaus Wirth das System OBERON,
ein Nachfolger von MODULA-2
• 1990: C++ wird überarbeitet und es entsteht C++ Version 2.0
• 1991: Visual BASIC entsteht.
• 1995: Die Programmiersprache ADA wird überarbeitet und von einem ANSI Komitee
standardisiert zu ADA95
1.6. Die Rechner der fünften Generation
In dieser Rechnergeneration wurde folgendes entwickelt bzw. eingesetzt:
- größere Packungsdichte auf den Chips und dadurch größere und schnellere Speicher.
- Man spricht von 1 Million Transistoren auf einem Chip
- widearea Netzwerke
- künstliche Intelligenz und Expertensysteme
- VHLSI (very high large scale integration)
- 3D-Prozessoren
- selbstlernende Systeme (Artificial Intelligence)
8
1. Geschichte und Aufgaben der Informatik
- Software in Silicon
- natürliche sprachliche Systeme
Diese Rechnergeneration ist mit großen Ankündigungen gestartet und hat vieles, was
sie erreichen wollte, nicht erlangt. Speziell in Japan wurden Milliardenbeträge in die
Entwicklung von Systemen mit künstlicher Intelligenz gesteckt, die nicht zu dem erwarteten
Ziel geführt haben. Folgende Vorhaben wurden nicht erreicht:
„Der Computer, der denkt wie der Mensch“,
„Spracherkennung fließender Rede“,
„Automatische Übersetzung“,
„BIOChips“,
„Microprozessoren mit Lichtwellenleitern“
Dagegen haben sich in anderen Gebieten umwerfende Entwicklungen ereignet:
−→ Neue Mikroprozessortechnologie:
- RISC Hardware statt CISC
- General Purpose CPU’s
- Pipelineing und Parallelrechner
−→ Weltweite Vernetzung von Rechnern
- Internet
−→ Multimediasysteme auf dem PC
1.7. Die Rechnergenerationen bis ca. 1990 im Überblick
Tabelle 1.1 auf Seite 9 fasst die Rechnergenerationen bis ca. 1990 im Überblick zusammen.
Gespeicherte
Programme,
Lochkarten
2 Kbyte Speicher,
10KIPS
Schnelligkeit
erste
1946 – 65
ENIAC, UNIVAC, IBM
701
Röhrenrechner,
Dezimalsystem
Software
Eigenheiten
Generation
Jahr
Rechner
2 Mbyte Speicher, 5
MIPS
dritte
1964 – 81
IBM 360, PdP 11,
CYBER 205
IC-Technik,
Microprozessoren
(4,8,16 BIT), LSI,
Minicomputer,
Magnetplatten
PASCAL, LIPS,
Computergraphik,
Timesharing
C, UNIX, ADA,
PROLOG,
Objektorientierte
Sprachen (C++),
Datenbanken
8 Mbyte Speicher, 30
MIPS
vierte
1982 – 89
CRAY XMP, SPERRY
1100/90, Sparc (SUN)
Multiprocessoren, (32
BIT) VLSI,
Microcomputer,
Optische Platten
Tabelle 1.1.: Die Rechnergenerationen bis ca. 1990 im Überblick
32 Kbyte Speicher,
2000 KIPS
FORTRAN, ALGOL,
COBOL
Transistortechnik,
Binärsystem
zweite
1957 – 63
CDC 6600, IBM 306
1 Gbyte Speicher, Giga
Flops
Multimediale
Betriebssysteme,
Expertensysteme
RISC, Mulitprocessoren
(64 BIT), Optische und
neuronale Bausteine
fünfte
ab 1989
CRAY T3D
1.7. Die Rechnergenerationen bis ca. 1990 im Überblick
9
10
1. Geschichte und Aufgaben der Informatik
1.8. Verwendete Abkürzungen
IC
– Integrated Circuit (= Transistor)
LIS
– Large Scale Integration: mehr als 1000 Transistoren auf einem Baustein
VLSI
– Very Large Scale Integration: mehr als 100000 Transistoren auf einem Baustein
Byte
– 8 Bit, wird benötigt, um einem Buchstaben zu speichern.
Kbyte – 1000 Byte,
Mbyte – 100000 Byte, 1000 Kbyte,
Gbyte – 10 hoch 9 Byte, 1000 Mbyte
IPS
– Instructions per Second,
MIPS
– 1 Million Instruktionen pro Sekunde
Flops – „Floating Point“-Operationen pro Sekunde
2. Die Programmiersprache Perl
2.1. Allgemeines zu Perl
Die Progammiersprache Perl wurde von Larry Wall erfunden und in seinem Buch Programming Perl 1991 (LW00) veröffentlicht. Der Name perl ist die Abkürzung für „Practical
Extraction and Report Language“.
Perl gibt es momentan in der Version 5.x und wird über eine zentrale Homepage verwaltet.
Die Version 6 ist schon seit einiger Zeit mit vielen, nahezu ’revolutionären’ Neuigkeiten
angekündigt, aber noch in der Entwicklung.
http://language.perl.com
In dieser Homepage finden sich Verweise zu aktuellen Softwarepaketen, Modulen und
Dokumentationen.
Larry Wall schreibt folgendes zu Perl:
(aus http://language.perl.com/info/synopsis.html, Adresse Stand: Nov 97)
Perl is an interpreted language optimized for scanning arbitrary text files,
extracting information from those text files, and printing reports based on that
information. It’s also a good language for many system management tasks. The
language is intended to be practical (easy to use, efficient, complete) rather
than beautiful (tiny, elegant, minimal). It combines (in the author’s opinion,
anyway) some of the best features of C, sed, awk, and sh, so people familiar
with those languages should have little difficulty with it. (Language historians
will also note some vestiges of csh, Pascal, and even BASIC-PLUS.) Expression
syntax corresponds quite closely to C Expression syntax. Unlike most Unix
utilities, Perl does not arbitrarily limit the size of your data–if you’ve got
the memory, Perl can slurp in your whole file as a single String. Recursion is
of unlimited depth. And the hash tables used by associative arrays grow as
necessary to prevent degraded performance. Perl uses sophisticated pattern
matching techniques to scan large amounts of data very quickly. Although
optimized for scanning text, Perl can also deal with binary data, and can
make dbm files look like associative arrays (where dbm is available). Setuid
Perl scripts are safer than C programs through a dataflow tracing mechanism
which prevents many stupid security holes. If you have a problem that would
ordinarily use sed or awk or sh, but it exceeds their capabilities or must run a
little faster, and you don’t want to write the silly thing in C, then Perl may be
for you. There are also translators to turn your sed and awk scripts into Perl
scripts.
2.2. Kurzübersicht zu Perl
Ziel der Programmiersprache war es, einfache Programmierprobleme einfach ausdrücken
zu können. Es sollten keine Variablen deklariert, keine Typen festgelegt werden. Der
Umgang mit Dateien sollte so einfach wie möglich sein. Stringvergleiche sollten über
mächtige reguläre Ausdrücke realisiert werden können. Die Programmiersprache Perl wurde
stark vom Betriebssystem UNIX und der Programmiersprache C beeinflusst und wurde
zu Beginn hauptsächlich zur Abarbeitung von Texten und Aufrufen von Diensten für
11
12
2. Die Programmiersprache Perl
das Betriebssystem eingesetzt. Nach und nach wurden weitere Programmbibliotheken für
Perl entwickelt, die es ermöglichen, Perl in nahezu allen Bereichen der Arbeit mit dem
Betriebssystem einzusetzen. Die großen Möglichkeiten, die Perl für die Bearbeitung von
Texten bereitstellt, haben auch dazu geführt, dass Perl in der Textbearbeitung mehr und
mehr eingesetzt wird. Die Entwickler sagen zwar, dass es sehr leicht ist, Perl-Programme
zu schreiben, vergessen aber, dass dies nur für Programmierer zutrifft, die Namens- und
Zeichenkonventionen von UNIX und C beherrschen und außerdem in der Lage sind,
mit regulären Ausdrücken umzugehen. Die vorherige Kurzbeschreibung von Perl wurde
hauptsächlich aus dem Buch „Programming Perl“ (LW00) entnommen. Perl ist eine
interpretierende Programmiersprache. Programme werden also nicht kompiliert und gelinkt,
sondern es wird der Sourcecode vom Programm perl direkt interpretiert.
Eine sehr gut Einführung in das Programmieren mit PERL findet sich im Buch von Randal
L. Schwarz (TP01)
2.3. Aufbau eines Perl Programms
2.3.1. Das erste Perl-Programm
#!/ usr / bin / perl
# Erstes Perl Programm
use strict ;
{
print (" Hallo wie geht ' s \ n ");
}
Formatierungskonvention:
• Die Variablendeklaration und die Anweisungen des Hauptprogramms werden 24 Zeichen eingerückt, die Einrücktiefe wird im gesamten Programm bei Blöcken
beibehalten. Zur Einrückung keine Tabstops verwenden! Die meisten grafischen
Editoren unterstützen das Feature: Obwohl sie bei diesen Editoren die Tabulatortaste
drücken, werden in der Datei Leerzeichen eingefügt.
• Alle Anweisungen stehen untereinander
2.4. Start eines Perl Programms
13
• pro Zeile nur eine Anweisung
Aus historischen Gründen steht hier das erste C-Programm, das in der ersten Vorlesung
„Einführung zur Programmierung“ im Jahre 1992 angegeben wurde:
/*
*/
Filename : hallo . c
Schreibt Text auf den Bildschirm
# include < stdio .h >
main ()
{
puts (" Hallo , hier ist der Sepp .");
}
2.4. Start eines Perl Programms
Perl Programme sind keine Maschinenprogramme, sondern Textdateien, die von Perl
interpretiert werden. Nachdem das Perl Programm in einer Datei abgespeichert wurde,
kann es mit dem Befehl
perl datei
gestartet werden. Damit der Befehl perl datei auf einem Rechner funktioniert, müssen aber
einige Bedingungen erfüllt sein:
• Das Programm perl wurde auf dem Rechner installiert.
• Das Programm perl muss in einem Verzeichnis installiert sein, das Aufgrund des
Inhalts der PATH Umgebungsvariable durchsucht wird.
(Im allgemeinen /usr/bin, oder /usr/local/bin)
Werden die Zugriffsrechte der Datei unter UNIX auf ausführbar (executable) gesetzt, kann
man das Programm selbst als Befehl aufrufen, wenn die erste Zeile des Perl Programms
eine sogenannte ident - Line enthält in der Perl als Befehl steht.
(Im Allgemeinen: #!/usr/bin/perl)
2.5. Editieren und Starten eines Perl - Programms mit dem UNIX
Programm kate
In der folgenden Abbildung 2.1 wird ein Screenshot des KATE Editors unter LINUX
gezeigt. Hier ist zu sehen, wie eine PERL Datei mit Hilfe von Kate bearbeitet werden kann.
Eine genauere Beschreibung des KATE Editors finden sie im Kapitel LINUX 7.1 und dort
im Abschnitt 7.3.2, „Aufrufen des kate Editors“ auf Seite 106.
14
2. Die Programmiersprache Perl
Abbildung 2.1.: Editor:Kate
2.5.1. Bemerkungen zur Syntax von Perl Programmen
Perl Programme haben ein freies Format, das heißt, dass Leerzeichen zwischen den Variablen
oder Programmzeilen keine Rolle spielen. Theoretisch könnte ein Perl Programm auf
einer Zeile stehen. Es wird aber empfohlen, dass zur besseren Lesbarkeit Leerzeichen
eingestreut werden. Zur Formatierung empfiehlt es sich keine Tabulatoren zu verwenden,
da die Position der Tabulatoren auf unterschiedlichen Systemen verschieden sein können.
Außerdem verbieten Programmiersprachen wie Python den Einsatz von Tabulatoren als
Formatierungselement.
• Jedes Perl Statement endet mit einem Semikolon.
• Das Zeichen # definiert den nachfolgenden Text bis zum Zeilenende als Kommentar
und ist für das Perl Programm irrelevant.
2.6. Datenstrukturen 1: Skalare und Listen
15
2.6. Datenstrukturen 1: Skalare und Listen
2.6.1. Vorbemerkung
Die Elemente eines Programms sollen das zu programmierende Sachgebiet so realistisch
wie möglich wiederspiegeln. Deshalb wählt der Programmierer dementsprechend die
• Datenstrukturen
• Operationen
aus einer Programmiersprache, die der Realität am nächsten kommen.
Die Datenstrukturen bestimmen die Menge von Konstanten und Variablen, die in einem
Programm verwendet werden können.
Die wichtigsten Operationen innerhalb von Datenstrukturen sind:
• Zuweisung
• Vergleich
2.6.2. Einfache Datenstrukturen: Skalare
Die einfachen Datenstrukturen sind die Standardtypen einer Programmiersprache. Für sie
sind Operatoren und Operationen definiert. Die Struktur im Speicher ist eindeutig festgelegt
und kann vom Programmierer nicht verändert werden. In Perl werden die einfachen
Standardtypen Skalare genannt. Diese umfassen Numerische Typen und Buchstabenketten.
Buchstabenketten heißen auch Strings.
In Perl gibt es folgende numerische Standard-Typen numerical literals
• ganze Zahlen
– Operationen: +, - *, /, %
– Beispiel:1, 2, -123, Hexadezimalzahl: 0xaff, Oktalzahl : 0372
• reelle Zahlen
– Operationen: +, - *, /
– Beispiel: 1.2, -3E4, -0.06
In Perl gibt es folgenden String Standard-Typen string literals
• strings
– Die Buchstabenkette muss bei Perl in Double Quotes eingeschlossen werden
– Operationen: . und x
– Beispiel: “abcde”, “a”
2.6.3. Zusammengesetzte Datenstrukturen: Listen
Bei zusammengesetzten Datenstrukturen werden beliebige Datenstrukturen zu einem
Datentyp zusammengefasst.
Die einfachste zusammengesetzte Datenstruktur ist die Strukturart Liste. Listen werden
auch Felder (Arrays) genannt. In Perl werden Listen dadurch kreiert, dass Skalare, mit
Komma getrennt, hintereinander aufgelistet und mit runden Klammern umschlossen werden:
(Element1 , Element2 , . . . ,Elementn )
16
2. Die Programmiersprache Perl
Die Reihenfolge der Auflistung definiert die Position der einzelnen Elemente innerhalb der
Liste. Außerdem wird ihnen eine Positionsnummer, bzw. ein Index zugeordnet. Das erste
Element bekommt die Positionsnummer (=Index) 0 das zweite die Nummer 1, das n-te
Element die Positionsnummer n-1.
Beispiel 2.1
("Moni", "Sepp", "Franz", "Müller")
Elementnummer
erstes Element
zweites Element
drittes Element
viertes Element
Index
0
1
2
3
Wert
“Moni”
“Sepp”
“Franz”
“Müller”
Tabelle 2.1.: Elemente in einer Liste
Das besondere Merkmal von Listen ist, dass die einzelnen Elemente über die Positionsnummer, den sogenannten Index angesprochen werden können.
2.7. Variablen
Um in einer Programmiersprache mit Daten zu arbeiten, muss man Variablen für den
entsprechenden Datentyp deklarieren. Der Name der Variablen ist dann ein Synonym für
den Speicherbereich, unter dem der Wert abgespeichert wird. Unter dem Variablennamen
können auf eindeutige Art Werte in diesen Bereich abgelegt und herausgelesen werden. Als
Variablennamen kann man beliebige Zeichenketten aus Buchstaben und Zahlen verwenden,
wobei der Name mit einem Buchstaben beginnen muss und kein Leerzeichen enthalten darf.
In Perl werden Groß- und Kleinbuchstaben in Variablennamen unterschieden.
Beispiel 2.2: Variablennamen
zulässige Variablennamen :
wert
x1
X1
unterscheidet sich vom kleingeschriebenen x1
unzulässige Variablennamen :
1wert beginnt mit einer Zahl
as
enthält ein Leerzeichen
In Perl muss bei jeder Variablen festgelegt werden, wie der Wert der Variablen interpretiert
werden soll. Die Art der Interpretation wird von speziellen Zeichen am Anfang der Variablen
definiert.
• Zugriff auf den Wert einer Variablen als Skalar: Der Variablenname beginnt mit
einem Dollar ($). Die Variable wird den Wert als Skalar speichern, bzw. zurückgeben:
z . B . $wert
• Zugriff auf den Wert einer Variablen als Liste: Der Variablenname beginnt mit einem
at (@). Die Variable soll den Wert einer Liste speichern, bzw. zurückgeben:
z . B . @namen
2.7. Variablen
17
2.7.1. Deklaration
Die Programmiersprache Perl schreibt nicht vor, dass eine Variable vor ihrem Gebrauch
deklariert werden muss. Für die Übersichtlichkeit, zur Vermeidung von Tippfehlern und
um einen guten Programmierstil zu gewährleisten, sollte man die Variablen aber trotzdem
deklarieren.
Schreibt man folgende use-Zeile: use strict; schaltet Perl zahlreiche syntaktische Überprüfungen ein, es akzeptiert dann z.B. nur zuvor deklarierte Variablen. Wenn nur die
syntaktische Überprüfung eingeschaltet werden soll, kann man die use strict Anweisung
mit einem Zusatz 'vars' einschränken:
use strict 'vars';
Mit dieser Anweisung überprüft der Perl-Interpreter beim Aufruf der Perldatei, ob alle
Variablen richtig deklariert wurden. Damit kann der Programmierer Tippfehler oder
doppelte Deklarationen einer Variablen vermeiden.
Formatierungskonvention:
• Verwenden Sie sprechende Variablennamen!
$x = " Helsinki "
ist zwar schön kurz, aber spätestens zehn Zeilen später weiß niemand mehr, was diese
Variable beinhaltet.
$stadt , $ort
oder irgendwas Vergleichbares wären je nach Kontext sehr viel besser.
• Vermeiden Sie zu lange Variablennamen.
Beispiel 2.3
Skalare:
my $zahl ;
my $farbe ;
Listen:
my @namen ;
my @werte ;
Beispiel 2.4: Arbeiten mit Skalaren und Arrays
#!/ usr / bin / perl
# file :/ DieSprache / glueckszahlen . perl
# Demonstration von if - else - Anweisung
use strict ;
{
my @glueckszahlen ;
my $zahl ;
@glueckszahlen = ( 13 , 12 , 27 );
print (" Geben Sie eine Zahl ein , ich sage , ob es eine Glückszahl ist :\ n ");
$zahl = < >;
if ( $glueckszahlen [0] == $zahl ) {
print (" Die eingegebene Zahl ist identisch zur ersten Glückszahl \ n ");
}
18
2. Die Programmiersprache Perl
}
elsif ( $glueckszahlen [1] == $zahl ) {
print (" Die eingegebene Zahl ist identisch zur zweiten Glückszahl \ n ");
}
elsif ( $glueckszahlen [2] == $zahl ) {
print (" Die eingegebene Zahl ist identisch zur dritten Glückszahl \ n ");
}
Exkurs:
Bei der Programmiersprache Perl wird bei der ersten Verwendung einer Variablen der
notwendige Datenbereich sofort alloziert. Diese Konvention führt bei großen Programmen
schnell zu Programmierfehlern, da Tippfehler in Variablennamen nicht erkannt werden,
sondern eine neue Variable mit dem vertippten Namen deklariert wird. Deshalb empfehlen
wir, die verwendeten Variablen vor der Verwendung zu deklarieren.
Beispiel 2.5: Beispiel für einen Programmkopf
#!/ usr / bin / perl
# Muster für einen Programmkopf
use strict ;
{
my ( $zaehler );
# Deklaration
$zaehler = 2;
# Initialisierung
...
}
2.8. Ausdrücke
Mit Hilfe von Operatoren können Operanden verknüpft werden, um neue Werte zu berechnen. Die Verknüpfung von ein oder mehreren Operanden mit einem oder mehreren
Operatoren bezeichnet man als Expression, oder auch Ausdruck.
In Perl gibt es einfache numerische Ausdrücke, string Ausdrücke und relationale Ausdrücke.
Numerische Ausdrücke kombinieren numerische Werte mit numerischen Operatoren, String
Ausdrücke verknüpfen string Werte mit string Operatoren und relationale Ausdrücke
werden mit relationalen Operatoren gebildet.
In Ausdrücken können auch Variablen vorkommen, die dann gemäß der Operatoren und
des Variablentyps ausgewertet werden und deren Wert in die Berechnung des Ausdrucks
einfließt.
Beispiel 2.6: Ausdrücke
Arithmetische Ausdrücke:
2 +
2 /
2.3
2 *
3
5
- 4.2
$zahl
String Ausdrücke:
" max "." münchen "
relationale Ausdrücke:
1 <= 3
2.8. Ausdrücke
19
2.8.1. Wertzuweisung
Jeder Variablen kann ein Wert über Konstanten oder über einen Ausdruck seines Datentyps
zugewiesen werden. Skalarvariablen können Skalare, bzw. Ausdrücke die einen Skalar als
Ergebnis liefern, zugewiesen werden. Listenvariablen können Listen, bzw. Ausdrücke die
eine Liste als Ergebnis liefern, zugeordnet werden.
Skalare können intern numerische oder string Daten enthalten. Listen können sich intern
sowohl aus numerischen, als auch aus string Elementen zusammensetzen.
Der Typ des Wertes, der in einer Variable zum ersten Mal gespeichert wird, legt den
internen Standardtyp der Variable fest. Bei Zuweisung einer Zahl wird der Variablen der
interne Datentyp: Numerischer Standardtyp zugeordnet.
Bei der Zuweisung eines Strings wird der Variable der interne Datentyp: String Standardtyp
zugeordnet.
2.8.1.1. Zuweisung einer Konstanten
Variablen wird bei der Initialisierung meistens eine Konstante zugewiesen. Die erste
Wertzuweisung einer Variable legt den internen Standardtyp der Variable fest.
Beispiel 2.7: Variableninitialisierung
# Skalare Variable , Interner Standardtyp : Numerisch
$x =5;
# Skalare Variable , Interner Standardtyp : String
$farbe = " rot ";
# Listen Variable , Interne Standardtypen : String , String , String
@namen = (" moni " ," gabi " ," martin ");
# Listen Variable , Interne Standardtypen :
#
Numerisch , Numerisch , Numerisch , Numerisch , Numerisch
@werte = (1 ,2 ,3 ,4 ,5);
# Listen Variable , Interne Standardtypen :
#
String , String , Numerisch , Numerisch , Numerisch
@eintrag = (" Katja " ," Putin " ,20 ,3 ,1974);
2.8.1.2. Zuweisung eines Ausdrucks
Variablen kann auch der Wert eines Ausdrucks zugewiesen werden. Bei der Zuweisung darf
sich aber der Wert des Ausdrucks nicht mit der Datenstruktur der Variablen (Skalar oder
Liste) und dem internen Standardtyp (numerisch oder string) widersprechen.
Formatierungskonvention:
• Schreiben Sie nie mehrere Zuweisungen in einer Zeile
• Wenn mehrere Zuweisungen in nachfolgenden Zeilen stehen, sollen die Zuweisungszeichen untereinander stehen.
• Verwenden Sie zur Ausrichtung keine Tabulatoren, sondern Leerzeichen
20
2. Die Programmiersprache Perl
Beispiel 2.8: arithmetischer Ausdruck
my $erste_zahl = 2;
my $zweite_zahl = 4;
$erste_zahl = $erste_zahl * $zweite_zahl ;
$erste_zahl = $erste_zahl + 1;
Bei einer Wertzuweisung wird der Wert des Ausdrucks auf der rechten Seite des Gleichheitszeichens berechnet und der Variablen links vom Gleichheitszeichen zugewiesen. Die
rechte Seite vom Gleichheitszeichen wird rvalue genannt, die linke Seite lvalue.
rvalues müssen immer einen Wert ergeben.
lvalues müssen immer eine Variable sein.
Beispiel 2.9: Wertzuweisung, unzulässiges Beispiel
2 = $erste_zahl * $zweite_zahl ;
# ( Zahl 2 als lvalue ist keine Variable )
In einem Ausdruck kann auch der Aufruf einer Subroutine vorkommen, deren Ergebnis
dann weiterverwendet wird.
Beispiel 2.10: Konvertieren eines Stringskalars in eine Buchstabenliste
Konvertieren eines Stringskalars in eine Buchstabenliste und Ermittlung der Anzahl der
Buchstaben in einem String.
$name
= " abcd ";
@buchstaben
= split (// , $name );
$string_laenge = length ( $name );
2.8.2. Einlesen der Daten vom Terminal
Zum Lesen von Daten von der Tastatur gibt es in Perl keine spezielle Leseroutine, das
Lesen der Daten von der Tastatur wird wie das Lesen von einer Datei realisiert. Unter Perl
und auch unter UNIX kann die Tastatur über den Filehandle STDIN angesprochen werden.
Erklärung: Ein Filehandle ist der Name des Kanals (z.B. eine Datei), über den die Einoder Ausgabe erfolgt. Ihre Benennung unterliegt den gleichen Kriterien wie die Benennung
von Variablen, sie bestehen aber aus Großbuchstaben und sind von spitzen Klammern
(Diamantoperator) umschlossen.
Es gibt 6 eingebaute, intern belegte Namen von Filehandles:
STDIN, STDOUT, STDERR, DATA, ARGV, ARGVOUT.
Die „Datei“ Tastatur wird beim Starten eines Programms automatisch geöffnet und ist
über den Filehandle STDIN während des ganzen Programms ansprechbar.
Beispiel 2.11: Einlesen vom Terminal
Folgende Anweisung liest vom Terminal einen String und speichert ihn unter der skalaren
Variable $str ab:
print (" Bitte geben Sie einen String ein > > >");
$str = < STDIN >; # oder $str = < >
print (" Die Eingabe war $str ,");
print (" Ende ");
2.8. Ausdrücke
21
Der Benutzer startet das Perl Programm, es erscheint der Text
Bitte geben Sie einen String ein >>>
Der Benutzer gibt folgenden String am Terminal ein
Hallo
Damit des Perl Programm die Eingabe bearbeitet, muss der Benutzer nach der Eingabe
der Buchstaben die RETURN Taste drücken. Der Benutzer hat also folgendes eingegeben:
Hallo < return >
Daraufhin beginnt Perl die eingegebenen Daten zu bearbeiten. Perl liest die eingegebenen
Buchstaben, inklusive des RETURN Zeichens vom Terminal und weist die gelesenen
Buchstaben der Variablen zu. Perl speichert somit die Eingabe "Hallo" inklusive des
RETURN Zeichens. Das Return Zeichen wird intern als special Character \n (=newline)
Zeichen in $str abgespeichert. Dies ergibt folgenden Speicherinhalt:
$str = H a l l o \ n
Bei der Ausgabe eines Strings wird der \n Buchstabe wieder als Zeilenumbruch interpretiert,
so dass die Ausgabe des Strings \$str folgende Ausgabe auf dem Terminal erzeugt:
Die Eingabe war Hallo
, Ende
Da der Benutzer im allgemeinen nur an den eingegeben Zeichen, nicht aber am \n Zeichen
interessiert ist, gibt es in Perl die spezielle Funktion:
chomp ( ... );
die ein \n Zeichen am Ende des Strings entfernt.
Das Programm dazu lautet:
print (" Bitte geben
$str = < STDIN >;
# Im String steht
chomp ( $str );
# Im String steht
print (" Die Eingabe
print (" Ende \ n ");
Sie einen String ein > > >");
# Eingabe von " Hallo < RETURN >"
" Hallo \ n "
# Entfernt \ n am Ende des Strings
" Hallo "
war $str ,");
Das Programm liefert folgende Ausgabe:
Die Eingabe war Hallo , Ende
22
2. Die Programmiersprache Perl
Beispiel 2.12: Arbeit mit Variablen
#!/ usr / bin / perl
# file :/ DieSprache / vardeklaration . perl
# Demonstration von Skalaren und Listen
use strict ;
{
my $x ;
my $y ;
my $a ;
my $b ;
my $c ;
my $anz_buchst ;
my $name ;
my $farbe ;
my $s_farbe ;
my @namen ;
my @werte ;
my @eintrag ;
my @buchstaben ;
print (" Demonstration SKALARE , LISTEN \ n ");
$x
$y
$farbe
@namen
@werte
@eintrag
print ("
print ("
print ("
print ("
print ("
print ("
=
=
=
=
=
=
1;
2.4;
" rot ";
( " max " , " moni " , " sepp " );
( 1 , 2 , 3 , 4 , 5 , 6 );
( " Moni " , " Müller " , 29 , 10 , 1972 );
x = $x \ n ");
y = $x \ n ");
Farbe = $farbe \ n ");
Name = @namen \ n ");
Werte = @werte \ n ");
Eintrag = @eintrag \ n ");
#
# mit Umlauten :
#
print (" Demonstration Umlaute \ n ");
$s_farbe = " grün ";
print (" Eine schöne Farbe ist $s_farbe \ n ");
}
#
# Einlesen von Skalaren :
#
print (" Bitte geben Sie eine Zahl ein > > >");
$x = < STDIN >;
chomp ( $x );
print (" Danke , Die Eingabe war : $x \ n ");
print (" Bitte geben Sie eine Farbe ein ( Auch mit Umlauten ) > > >");
$s_farbe = < STDIN >;
chomp ( $s_farbe );
print (" Danke , Die Eingabe war : $s_farbe \ n ");
2.9. Operatoren
23
2.9. Operatoren
Mit Hilfe von Operatoren können Ausdrücke geschaffen werden, die Variablen oder Konstanten ihrer Definition entsprechend verknüpfen:
z.B.
<operand>
$zahl1
<operator>
*
<operand>
$zahl2
Für jeden internen Datentyp gibt es genau festgelegte Operatoren.
Achtung: Die Kombination falscher Operanden und Operatoren führt in Perl meist zu
Rechenfehlern, nicht aber zum Programmabsturz.
2.9.1. arithmetische Operatoren
+
*
/
% modulo
2.9.2. string Operatoren
In Perl wird der interne Standardtyp string vom internen numerischen Standardtyp unterschieden. Für Strings und für Zahlen gibt es eigene Operatoren. Beachten Sie, dass
sprachspezifische Eigenheiten nur berücksichtigt werden, wenn „use locale“ verwendet wird.
Zur Konkatenation zweier Strings gibt es den
K o nk at en ati on so per at or
.
Zur Vervielfältigung von Strings gibt es den
V e r v i e l f ä l t i g u n gs o p e r a t o r
x
Beispiel 2.13: string Operatoren
my $a =" AAA ";
my $b =" BBB ";
my $c ;
Konkatenieren von $a und $b:
$c = $a . $b ;
ergibt : $c = " AAABBB "
Vervielfältigung von a :
$c = $a x 3;
ergibt : $c = " AAAAAAAAA "
2.9.3. Grundlagen: Logische Ausdrücke
Aussagen, denen man einen Wahrheitswert, nämlich wahr oder falsch zuordnen kann,
bezeichnet man als logische Aussagen.
Eine Aussage hat den Wahrheitswert wahr (true) falls sie zutrifft und falsch (false) falls
sie nicht zutrifft.
Bei der Auswertung von beliebigen logischen Aussagen hilft die Theorie der Aussagenlogik.
Sei W(A) der Wahrheitswert der Aussage A:
W ( A ) = true , falls die Aussage A wahr ist
W ( A ) = false , falls die Aussage A falsch ist
24
2. Die Programmiersprache Perl
Logische Ausdrücke können mit Hilfe von Logischen Operatoren aus Primitiven Objekten gebildet werden. Zum Vergleich von Zahlen und Buchstaben gibt es je 6 Vergleichsoperatoren,
die in der Tabelle 2.2 gezeigt werden.
Operator für
Zahlen
Operator für
Name
Buchstaben
und Buchstabenfolgen
(Zeichenketten)
Beispiel
==
eq
gleich
!=
<
<=
>
>=
ne
lt
le
gt
ge
ungleich
kleiner
kleiner gleich
größer
größer gleich
1 == 2
’a’ eq ’b’
a != 4
2 < 3
2 <= 3
4 > 5
4 >= 5
Negation
!=
==
>=
>
<=
<
Tabelle 2.2.: Logische Operatoren
Aussagen können mit UND (and, &&) bzw. ODER (or, ||) verknüpft werden. Aussagen
können mit NEIN (not, !) negiert werden.
• Es gilt Aussage (A) and Aussage (B), falls Aussage (A) UND Aussage (B) gelten.
• Es gilt Aussage (A) or Aussage (B), falls Aussage (A) ODER Aussage (B) gelten.
Bei der Auswertung von logischen Aussagen helfen sogenannte Wahrheitstafeln, die in der
Tabelle 2.3 abgebildet sind.
Aussage
Aussage
A
B
true
true
false
false
true
false
true
false
UND
A and B
A && B
true
false
false
false
ODER
A or B
A || B
true
true
true
false
Negation
not (A)
!(A)
false
false
true
true
Tabelle 2.3.: Logische Aussagen
2.9.4. Vergleichsoperatoren
Vergleichsoperatoren können Werte logisch vergleichen. Ob zum Beispiel eine Zahl kleiner ist
als eine andere oder ein String identisch zu einem anderen ist. In Perl muss man je nachdem
ob numerische oder string Werte verglichen werden den zuständigen Vergleichsoperator
verwenden, wie sie in der Tabelle 2.4 sehen.
Für die Beispiele gilt:
my
my
my
my
$a
$b
$str1
$str2
=
=
=
=
1;
2;
" abcs ";
" abdede ";
2.9. Operatoren
25
Operator für
numerische
Werte
Operator für
string Werte
Name
==
eq
gleich
!=
ne
ungleich
<
<=
lt
le
kleiner
kleiner gleich
>
gt
größer
>=
ge
größer gleich
Beispiel
Negation
$a == $b
"abc"eq $str1
! $a
ne $str
$a < 3
2 <= 3
$a > 5
$str > ’abc’
4 >= 5
!=
==
>=
>
<=
<
Tabelle 2.4.: Vergleichsoperatoren
Beispiel 2.14: Vergleichsoperatoren bei ganzen Zahlen
#!/ usr / bin / perl
# file :/ DieSprache / verOpZahlen . perl
# Demonstration von Vergleichsoperatoren bei Zahlen
use strict ;
{
my $eingabe = 0;
my $nummer = 5;
}
if ( $eingabe != $nummer ) {
print (" Bitte raten Sie eine Nummer zwischen 0 und 9\ n ");
print (" Bitte Eingabe der Nummer > > >");
$eingabe = < STDIN >;
chomp ( $eingabe );
if ( $eingabe != $nummer ) {
print (" Ha , Ha , Ha , Eingabe war falsch \ n ");
}
}
Beispiel 2.15: Vergleichsoperatoren bei Strings
#!/ usr / bin / perl
# file :/ DieSprache / verOpString . perl
# Demonstration von Vergleichsoperatoren bei Strings
use strict ;
{
my $eingabe
= "";
my $wochentag = " Montag ";
print (" Bitte raten Sie einen Wochentag \ n ");
print (" Bitte Eingabe des Wochentags > > >");
$eingabe = < STDIN >;
chomp ( $eingabe );
if ( $eingabe ne $wochentag ) {
print (" Ha , Ha , Ha , Eingabe war falsch \ n ");
}
if ( $eingabe lt $wochentag ) {
print (" Ein Tipp : Ihre Eingabe war alphabetisch kleiner \ n ");
}
if ( $eingabe gt $wochentag ) {
print (" Ein Tipp : Ihre Eingabe war alphabetisch größer \ n ");
} else {
26
2. Die Programmiersprache Perl
}
print (" Endlich !!!\ n ");
}
print ( " Ihre Eingabe war $eingabe \ n " );
print ( " Der Wochentag war $wochentag \ n " );
In Perl sind folgende Werte in einem logischen Ausdruck wahr (siehe 2.5) :
Wert=wahr
1
"␣"
"hello"
Beispiel
my $i = 1;
if ($i) {
my $i = "␣";
if ($i) {
my $i = "hello";
if ($i) {
Beschreibung
Der numerische Wert 1
ist immer true
Das Leerzeichen als string
ist immer true
Jeder String ist immer true
Tabelle 2.5.: Wahre Werte in einem logischen Ausdruck
In Perl sind folgende Werte in einem logischen Ausdruck falsch (siehe 2.6) :
Wert = falsch
0
""
"0"
Beispiel
my $i = 0;
if ($i) {
my $str = "";
if ($str) {
my $str = "0"
if ($i) {
Beschreibung
Der numerische Wert 0
ist immer "false"
Der leere String ist
immer false
Jeder String mit dem
einzigen Buchstaben 0
(Null) ist immer false
Tabelle 2.6.: Falsche Werte in einem logischen Ausdruck
2.10. Kontrollstrukturen
27
2.10. Kontrollstrukturen
Die Kontrollstrukturen kontrollieren den Ablauf des Programms. Sie verändern den Wert von
Variablen und bestimmen die Reihenfolge der Anweisungen, die im Programm ausgeführt
werden sollen.
in Perl gibt es folgende Kontrollstrukturen:
• einfache Zuweisungen, Statements
• Blöcke :
eine Anzahl von Statements die geklammert sind : { ... }
• Ablaufsteuerungsanweisungen:
if
if else
while
do while
do until
foreach
for
und weitere
• Subroutinen
2.10.1. Blöcke
Möchte man Ausdrücke zu einem einzigen Ausdruck zusammenfassen, muss man die
Ausdrücke mit geschweiften Klammern zusammenfassen. Vor der ersten Anweisung muss
eine öffnende geschweifte Klammer stehen, nach der letzten Anweisung eine schließende
geschweifte Klammer. Geklammerte Ausdrücke nennt man Block oder compound statement.
Am Anfang eines jeden Blocks können Variablen definiert werden, die nur innerhalb dieses
Blocks gelten.
Formatierungskonvention:
• Öffnende geschweifte Klammer in Blockeinleitungszeile
• Schließende geschweifte Klammer separat in der nächsten Zeile hinter der letzten
Anweisung. Die Einrücktiefe ist die gleiche wie die des ersten Zeichens des Blockeinleitungsstatements
• Die Anweisungen innerhalb des Blocks werden eingerückt und stehen untereinander
• Zur Einrückung keine Tabstops verwenden! Einrückung mit 2 oder 3 Leerzeichen
(die meisten grafischen Editoren unterstützen das Feature: Obwohl sie bei diesen
Editoren die Tabulatortaste drücken, werden in der Datei Leerzeichen eingefügt. Die
Einrücktiefe wird im gesamten Programm bei Blöcken beibehalten.)
Beispiel 2.16: Blöcke
#! usr / bin / perl
use strict ;
{
my $a ;
28
2. Die Programmiersprache Perl
}
my $zahl
my $wert
$a
$wert
=
=
=
=
100;
1;
$zahl ;
2;
2.10.2. Auswahlanweisung: if
if ( Expression ) {
Anweisungen
}
Die Expression muss ein auswertbarer logischer Ausdruck sein.
Falls der Wert der Expression wahr ist (siehe: Definition von Wahrheitswerten) werden die
Anweisungen innerhalb des Blocks ausgeführt.
Ist der Wert der Expression falsch, dann werden die Anweisungen übersprungen und die
Anweisungen hinter der geschweiften Klammer ausgeführt.
Falls die Anweisungen nur aus einer Anweisung bestehen, dann kann an der Stelle der
geklammerten Anweisungen auch ein einzelnes Statement stehen.
2.10.3. Auswahlanweisung: if...else
if ( Expression ) {
Anweisungen1
} else {
Anweisungen2
}
Die Expression muss ein auswertbarer logischer Ausdruck sein. Falls der Wert der Expression wahr ist, werden Anweisungen1 ausgeführt, sonst Anweisungen2
Formatierungskonvention:
• die Anweisungen werden mit einer geschweiften Klammer in der Zeile der if-Anweisung
geöffnet
• die Anweisungen werden 2-4 Zeichen eingerückt, die Einrücktiefe wird im gesamten
Block beibehalten
• die Anweisungen stehen untereinander
• jede Anweisung steht in einer eigenen Zeile
• schließende geschweifte Klammer separat in der nächsten Zeile hinter der letzten
Anweisung. Die Einrücktiefe ist die gleiche wie die der if -Anweisung
• eine eventuelle else Anweisung wird hinter der schließenden Klammer der if-Anweisung
fortgesetzt
• nachfolgende Anweisungen werden wie bei der if-Anweisung geklammert
Beispiel 2.17: if Anweisung
#!/ usr / bin / perl
# Demonstration der if - Anweisung
use strict ;
{
if ( $i == 0) {
print (" Ich bin gleich Null \ n ");
}
2.10. Kontrollstrukturen
}
29
if ( $i == 2) {
print (" i ist gleich 2 ");
}
else {
print (" i ist ungleich 2");
$i = 0;
}
2.10.4. Wiederholungsanweisung: while
while ( Expression ) {
Anweisungen
}
Die Expression muss ein auswertbarer logischer Ausdruck sein. Falls der Wert der Expression true ist, werden die Anweisungen innerhalb der geschweiften Klammer solange
ausgeführt, bis der Wert der Expression false ist.
Formatierungskonvention:
• die Anweisungen werden mit einer geschweiften Klammer in der Zeile der whileAnweisung geöffnet
• die Anweisungen werden 2-4 Zeichen eingerückt, die Einrücktiefe wird im gesamten
Programm bei Blöcken beibehalten
• die Anweisungen stehen untereinander
• jede Anweisung steht in einer eigenen Zeile
• schließende geschweifte Klammer separat in der nächsten Zeile hinter der letzten
Anweisung. Die Einrücktiefe ist die gleiche wie die der while-Anweisung
Beispiel 2.18: while Anweisung
#!/ usr / bin / perl
# file :/ DieSprache / whileAnweisung . perl
# Demonstration von while - Anweisung
use strict ;
{
my ( @glueckszahlen , $zahl , $zaehler );
$zaehler = 0;
print (" Geben Sie bitte Ihre 5 Glückszahlen ein :\ n ");
while ( $zaehler < 5 ) {
$glueckszahlen [ $zaehler ] = < >;
$zaehler ++;
}
print (" Danke !\ n ");
print (" Geben Sie eine Zahl ein , ich sage , ob es eine Glückszahl ist :\ n ");
$zahl = < >;
chomp ( $zahl );
}
while ( $zaehler >= 0 && $glueckszahlen [ $zaehler ] != $zahl ) {
$zaehler - -;
}
if ( $zaehler == -1 ) {
print (" $zahl ist keine Glückszahl \ n ");
} else {
print (" Ja , $zahl ist eine Glückszahl !\ n ");
}
30
2. Die Programmiersprache Perl
Beispiel 2.19: while Anweisung
#!/ usr / bin / perl
# Demonstration der while - Anweisung
use strict ;
{
my $i = 0;
while
( $i <10) {
print (" Zahl = ");
print (" $i \ n ");
$i = $i +1;
}
}
Beispiel 2.20: eine Zahl raten
Das Programm fordert den Benutzer auf, eine intern definierte Zahl zu erraten. Falls die
Zahlen nicht identisch sind, gibt es eine Fehlermeldung aus, aus der hervorgeht, ob die
eingegebene Zahl größer oder kleiner als die intern gespeicherte Zahl ist. Sind sie identisch,
dann soll eine Erfolgsmeldung ausgegeben werden. Der Benutzer wird nur maximal fünfmal
gefragt.
#!/ usr / bin / perl
# file :/ DieSprache / zahlRaten . perl
# Zahl erraten
use strict ;
{
my ( $zaehler , $zahl , $geraten , $versuche );
}
$zaehler = 0;
$zahl
= 5;
print (" Rate die Zahl !\ n ");
$geraten = < >;
while ( ( $zaehler < 4 ) && ( $geraten != $zahl ) ) {
if ( $geraten > $zahl ) {
print (" Die eingegebene Zahl ist groesser als die gespeicherte !\ n ");
} else {
print (" Die eingegebene Zahl ist kleiner als die gespeicherte !\ n ");
}
$versuche = 4 - $zaehler ;
print (" Verbleibende Versuche : $versuche \ n ");
print (" Probiers nochmal : ");
$geraten = < >;
$zaehler ++;
}
if ( $geraten == $zahl ) {
print (" Erraten !\ n ");
} else {
print (" Nicht erraten !\ n ");
}
2.10. Kontrollstrukturen
31
2.10.5. Wiederholungsanweisung: do while
do {
Anweisungen
} while ( Expression )
Die Expression muss ein auswertbarer logischer Ausdruck sein. Der Block wird solange
ausgeführt, wie der Wert von Expression true ist.
Formatierungskonvention:
• die Anweisungen werden mit einer geschweiften Klammer in der Zeile der doAnweisung geöffnet
• die Anweisungen werden 2-4 Zeichen eingerückt
• die Anweisungen stehen untereinander
• jede Anweisung steht in einer eigenen Zeile
• schließende geschweifte Klammer separat in der nächsten Zeile hinter der letzten
Anweisung. Die Einrücktiefe ist die gleiche wie die do-Anweisung
• dahinter steht die while Anweisung mit dem logischen Ausdruck Expression
Beispiel 2.21: do while Anweisung
#!/ usr / bin / perl
# Demostration der do - while - Anweisung
use strict ;
{
my $i = 20;
print (" Ich gebe alle geraden Zahlen zwischen 20 und 0 aus \ n ");
do {
print (" Zahl = ");
print (" $i \ n ");
$i = $i -2;
} while ( $i >= 0)
}
2.10.6. Wiederholungsanweisung: do...until
do {
Anweisungen
} until ( Expression )
Die Expression muss ein auswertbarer logischer Ausdruck sein. Der Block wird solange
ausgeführt, bis der Wert von Expression true ist.
Formatierungskonvention:
• wie bei der do ... while Anweisung
Beispiel 2.22: do until Anweisung
#!/ usr / bin / perl
# Demonstration von do - until - Anweisung
use strict ;
{
my $i = 0;
32
2. Die Programmiersprache Perl
}
do {
print (" Zahl = ");
print (" $i \ n ");
$i = $i +1;
} until ( $i > 10)
Der Unterschied zwischen while . . . und do . . . liegt darin, dass bei while zuerst die
Bedingung geprüft wird und dann der Block ausgeführt wird. Bei do . . . wird zuerst der
Block ausgeführt und dann die Bedingung geprüft. Die while Schleife terminiert dann, wenn
die Auswertung der Expression den logischen Wert false ergibt. Die do Schleife terminiert
genau beim logischen Gegenteil: Die Auswertung von Expression muss true ergeben, damit
die do Schleife terminiert.
2.10.7. Wiederholungsanweisung: foreach
foreach $element ( @liste ) {
Anweisungen
}
2.10.8. Wiederholungsanweisung: for
for ( $i =0; $i <5; $i ++)
Anweisungen
}
{
Beispiel 2.23: foreach und for Anweisung
#!/ usr / bin / perl
# Demonstration von foreach und for Anweisung
use strict ;
{
my @numbers = (2 ,4 ,6 , -10 ,12);
my $i ;
foreach $i ( @numbers ) {
print (" Zahl = $i \ n ");
}
for ( $i =0; $i <5; $i ++) {
print (" $i te Zahl = $numbers [ $i ] \ n ");
}
}
for ( $i =4; $i >=0; $i - -) {
print (" $i te Zahl = $numbers [ $i ] \ n ");
}
Es werden der Reihe nach die Elemente aus der Liste @liste der Variablen $element zugewiesen. Dann wird jedesmal der Block mit dem entsprechenden Variablenwert ausgeführt.
Beispiel 2.24: Liste
#!/ usr / bin / perl
# Beispiel für Array
use strict ;
{
my @farben = (" rot " ," gruen " ," blau ");
my $farbe ;
foreach $farbe ( @farben ) {
print (" Farbe = $farbe \ n ");
}
}
2.11. Lesen von Daten aus einer Datei
33
2.11. Lesen von Daten aus einer Datei
Zur permanenten Speicherung von Daten verwendet man in Betriebssystemen Dateien.
Dateien werden über einen Namen innerhalb eines Verzeichnisses (Ordner) eindeutig
identifiziert. Unter UNIX werden Dateien, die binäre Daten speichern, Binärdateien und
Dateien, die Texte speichern, Textdateien genannt. Unter UNIX wird eine Textdatei als
geordnete Folge oder „Strom“ stream von Zeichen (Bytes) betrachtet. Die einzelnen Zeilen
sind durch ein Zeilentrennzeichen (’\n’) getrennt.
Beispiel 2.25
Folgende 5 Zeilen werden mit einem Texteditor in die neue Datei file.txt geschrieben:
Eins
Zwei
Drei
4 5 6 7 8
Ende
Damit die Information des Zeilenumbruchs nicht verloren geht, wird in der Datei an die
Stelle des Zeilenumbruchs ein sogenannter Special Character eingefügt. Dieser Special
Character hat die Aufgabe bei der Ausgabe einen Zeilenumbruch zu bewirken. Der Special
Character hat bei UNIX den Octal Code 12 und heißt Newline (Abkürzung = nl)
Aus diesen Gründen wird auf der Festplatte der Inhalt folgendermaßen Zeichen für Zeichen
abgespeichert:
E i n s nl Z w e i nl D r e i nl 4 sp 5 sp 6 sp 7 sp 8 nl E n d e
wobei sp die Kodierung für Space und nl die Kodierung für newline ist.
Unter UNIX gibt es den Befehl od (Octal Dump) mit dem man den Inhalt einer Datei
Zeichen für Zeichen darstellen (=„dumpen“) kann. Dem Befehl muss man angeben, mit
welchem Format die Zeichen der Datei konvertiert werden sollen, bevor sie auf dem Terminal
ausgegeben werden. In der linken Spalte gibt der Befehl od die octale Bytenummer des
ersten Zeichens in der Datei aus, in den restlichen Spalten die Zeichen entsprechend der
ausgewählten Konvertierung.
(Zur weiteren Information zum Befehl od geben Sie den UNIX Befehl „man od“ ein.)
Beispiel 2.26: Ausgabe der Zeichen als OKTAL-Wert
> od -b file . txt
0000000 105 151 156 163 012 132 167 145 151 012 104 162 145 151 012 064
0000020 040 065 040 066 040 067 040 070 012 116 145 165 156 012 105 156
0000040 144 145
0000042
Beispiel 2.27: Ausgabe der Zeichen als ASCII-Wert
> od -a file . txt
0000000
E
i
0000020
sp
5
0000042
n
sp
s
6
nl
sp
Z
7
w
sp
e
8
i nl
nl E
D
n
r
d
e
e
i
nl
4
Befehle zur Ausgabe von Textdateien interpretieren die nl Zeichen bei der Ausgabe auf das
Terminal richtig und erzeugen einen Zeilenumbruch anstelle des Buchstabens nl.
34
2. Die Programmiersprache Perl
Beispiel 2.28: Textbefehl cat zur Ausgabe einer Textdatei
> cat file . txt
Eins
Zwei
Drei
4 5 6 7 8
Ende
2.11.1. Dateihandles
Möchte man den Inhalt der Datei in einem Perl Programm lesen, dann muss die Datei im
Perl Programm einem internen Dateihandle zugewiesen werden.
Außerhalb des Progamms
Filename
Innerhalb des Programms
Filehandle
Die Perlfunktion „open“ ordnet einer externen Datei einen internen Dateihandle zu und
setzt den Filepositionmarker auf den Anfang.
open ( filehandle , filename )
Zum Lesen der nächsten Zeichen hinter dem Filepositionmarker gibt es den sogenannten
Diamond-operator.
< filehandle >
Beispiel 2.29
open ( DATEI ," file . txt ")
Am Ende eines Programms muss der Filehandle wieder geschlossen werden:
close DATEI ;
Der Diamond-operator liefert als Ergebnis alle Zeichen aus der Datei die nach dem Filepositionmarker folgen, bis zum nächsten Zeilentrennzeichen (’\n’). Nach erfolgreichem Lesen
wird der Filepositionmarker hinter das zuletzt gelesene Zeichen gesetzt.
Falls der Filepositionmarker am Ende der Datei steht, wird bei erneutem Aufruf des
Diamond-operators ein leerer String zurückgeliefert.
Beispiel 2.30: Zeilenweises lesen aus der Datei „file.txt“
#!/ usr / bin / perl
# file :/ DieSprache / file . perl
# Demonstration Lesen aus einer Textdatei
use strict ;
{
my $filename = " file . txt ";
my $line ;
open ( EINGABE , $filename );
while ( $line = < EINGABE > ) {
chomp $line ;
# empfehlenswert zum Löschen des Zeilenumbruchs
print " $line \ n ";
}
close ( EINGABE );
}
Test mit der Datei zeilen.txt
Der Inhalt ist:
2.11. Lesen von Daten aus einer Datei
35
Erste
zweite
Nach dem Öffnen wird dem Filehandle EINGABE die Datei „zeilen.txt“ zugeordnet. Der
Filepositionmarker (!pos) steht am Anfang.
E
r
s
t
e
!pos
Lesen der ersten Zeile ergibt:
\n
z
w
e
i
t
e
\n
$line = " erste \ n ";
Der Filepositionmarker wird hinter den letzten gelesenen Buchstaben positioniert:
E
r
s
t
e
\n
z
w
e
i
t
e
\n
!pos
Lesen der zweiten Zeile ergibt:
$line = " zweite \ n ";
Der Filepositionmarker wird hinter den letzten gelesenen Buchstaben positioniert
E
r
s
t
e
\n
z
w
e
i
t
e
\n
!pos
Lesen der nächsten Zeile ergibt:
$line = "";
Es wird nichts gelesen. Der Diamondoperator liefert den leeren String. Der Inhalt von $line
wird auf Null gesetzt, die while Schleife terminiert !
Beispiel 2.31: Kopie einer Datei erzeugen
Das Programm erfragt den Namen einer Datei und erzeugt eine Kopie dieser Datei mit
dem Namen kopie.txt:
#!/ usr / bin / perl
# file :/ DieSprache / dateiCopy . perl
# Kopieren einer Textdatei
use strict ;
{
my ( $dateiname , $ausgabe , $zeile );
$ausgabe = " kopie . txt ";
print (" Bitte geben Sie einen Dateinamen ein , zum Kopieren der Datei > > > ");
$dateiname = < STDIN >;
chomp $dateiname ;
open ( DATEI ,
$dateiname );
open ( AUSGABE , " > $ausgabe " );
while ( $zeile = < DATEI > ) {
# kein chomp , damit Zeilenumbrueche erhalten bleiben
print AUSGABE $zeile ;
}
}
close DATEI ;
close AUSGABE ;
36
2. Die Programmiersprache Perl
2.12. Interne Repräsentation von Zahlen
Das Dezimalsystem:
Wenn wir eine Zahl, z.B: 253 lesen, gehen wir zunächst automatisch davon aus, dass es sich
um eine Zahl des Dezimalsystems handelt. Im Zehnersystem wird mit 10 verschiedenen
Ziffern gearbeitet, die durch die Ziffern 0-9 ausgedrückt werden.
Wir lesen die Ziffern nach folgendem Schema:
Einer:
100
Zehner:
101
Hunderter: 102
usw.
Daraus ergibt sich für die Zahl 253 folgende Darstellung:
2·102 + 5·101 + 3·100 = 253
Analog geht man auch bei anderen Zahlensystemen vor, nur benutzt man andere Werte als
Basis:
Das Binärsystem:
Im Gegensatz zum Dezimalsystem, bei dem die Basis 10 verwendet wird, nimmt man beim
Binärsystem die Basis 2 (=Übersetzung in Binärcode). Gültige Ziffern sind die 0 und die
1. Sollen nur positive ganze Zahlen dargestellt werden, kann man mit n Bit (Stellen) die
Zahlen von 0 bis 2n−1 darstellen. Die größte Zahl ist also 2n .
Darstellungen zu unterschiedlichen Basen:
Beispiel 2.32: Binärdarstellung von einer Dezimahlzahl
Dezimalzahl
1 · 20
1 · 21
+ 0 · 22
+ 1 · 23
11
=
=
=
=
=
= Binärzahl 1011
1
2
0
8
11
Darstellung negativer Werte:
Vorzeichenbit: das erste Bit zeigt das Vorzeichen an: 1 ist negativ, 0 ist positiv
Zweier Komplement :
bt − x = 1 +
t−1
P
i=0
(b − 1) · bi −
wird als (bt ) - x dargestellt.
t−1
P
i=0
ai · bi = 1 +
t−1
P
i=0
Darstellung im Zweierkomplement der Zahlen -4 bis +3:
-4
-3
-2
-1
=
=
=
=
100
101
110
111
0
1
2
3
=
=
=
=
000
001
010
011
(b − 1 − ai ) · bi
2.12. Interne Repräsentation von Zahlen
37
Darstellung reeller Werte:
x = m · be , e ganze Zahl
m ist die Mantisse, e der Exponent.
Erklärung: Die Mantisse ist die Ziffernstelle einer Gleitkommazahl.
Beispiel 2.33
Bei der Zahl 5,5 · 103 ist 5,5 die Mantisse, 3 der Exponent.
Beispiel 2.34
Dezimalzahl : 53 ,
Dezimalzahl : 63 ,
binäre Darstellung : 110101
binäre Darstellung : 111111
Das Oktalsystem:
In diesem System verwendet man die Basis 8, es sind die Ziffern 0,1,2,3,4,5,6,7 gültig.
Beispiel 2.35
Die Zahl 136 z.B. wird dargestellt als
2 · 82 + 1 · 81 + 0 · 80 = 210 als Oktalzahl
53(dezimal) = 65(oktal) = 6 · 81 + 5 · 80
63(dezimal) = 77(oktal) = 7 · 81 + 7 · 80
136 (dezimal) = 210(oktal) = 6 · 81 + 5 · 80
Das Hexadezimalsystem:
Beim Hexadezimalsystem wird die Zahl 16 als Basis zu Grunde gelegt. Für dieses System
benötigt man 16 Ziffern, es werden zu den Ziffern 0-9 für die fehlenden 6 Ziffern die
Buchstaben A-F verwendet.
Gültige „Ziffern“: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
Die Zahl 136 z.B. wird dargestellt als
8 · 161 + 8 · 160
Das Hexadezimalsystem wird häufig verwendet, da es sich letztlich um eine komfortable
Schreibweise des Binärsystems handelt. Es eignet sich durch seine Basis der vierten Zweierpotenz (16 = 24 ) zur relativ einfachen Darstellung von Binärzahlen. Ein Byte mit 8
Bit lässt sich in ein Halbbyte mit 4 Bit aufteilen. Das heißt, man kann ein Byte mit zwei
Stellen im Hexadezimalsystem darstellen.
Beispiel 2.36
53( dezimal )
63( dezimal )
=
=
35( hexadezimal )
3 F ( hexadezimal )
Beispiel 2.37: Darstellung der Dezimalzahl 60 im Speicher
60/2 = 30
30/2 = 15
15/2 = 7
7/2
=3
3/2
=1
1/2
=0
das entspricht
Rest
Rest
Rest
Rest
Rest
Rest
0
0
1
1
1
1
(Wertigkeit
(Wertigkeit
(Wertigkeit
(Wertigkeit
(Wertigkeit
(Wertigkeit
0.Stelle)
1.Stelle)
2.Stelle)
3.Stelle)
4.Stelle)
5.Stelle)
:| 1 | 1 | 1 | 1 | 0 | 0 |
38
2. Die Programmiersprache Perl
Beispiel 2.38: Darstellung der Zahl 60 als Oktalzahl im Speicher
60/8
7/8
|
=7
=0
7
|
Rest 4
Rest 7
4
12 (dezimal)
256 (dezimal)
64(dezimal)
(Wertigkeit 0.Stelle)
(Wertigkeit 1.Stelle)
|
1100 (binär)
100000000 (binär)
1000000 (binär)
14 (oktal)
400 (oktal)
100 (oktal)
C (hexadezimal)
100 (hexadezimal)
40 (hexadezimal)
2.13. Interne Repräsentation von Schriftzeichen
In der Tabelle 2.7 werden 7-bit-Codes für ASCII Buchstaben dargestellt.
2.13.1. Speicherung von Strings
Unter Strings (=string literale) werden in Perl Folgen von Buchstaben verstanden. Die
Buchstaben, die den String repräsentieren, müssen in Double Quotes zusammengefasst
werden. Im Speicher werden die Buchstaben entsprechend der ASCII oder UNICODE
Kodierung als ganzzahlige Werte einzeln der Reihe nach abgespeichert. Jeder String kennt
die Anzahl seiner Buchstaben.
2.13.2. Speicherung von Buchstaben
Da Buchstaben nicht direkt im Speicher abgebildet werden, wird jedem Zeichen (Buchstaben) eine ganze Zahl (Zeichencode) zugeordnet. Die Abbildung Buchstabe ⇒ Nummer
wurde im American National Standard Code for Information Interchange (ASCII) definiert,
wobei dieser Code in den ersten Versionen nur 7 Bit Zahlen verwendete. Somit konnte
diese Codierung nur 128 Zeichen kodieren, siehe Tabelle 2.7
2.13. Interne Repräsentation von Schriftzeichen
39
2.13.3. Zeichencodierung: ASCII, für Buchstaben, mit 7 Bit
000
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
HT
LF
VT
FF
CR
SO
SI
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
!
"
#
$
%
&
’
(
)
*
+
,
.
/
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
ˆ
_
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
‘
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
•
Tabelle 2.7.: Zeichencodierung: ASCII, für Buchstaben, mit 7 Bit
2.13.4. Bedeutung der Steuerzeichen
Die Buchstaben mit ASCII Code kleiner als 31 werden Steuerzeichen genannt und zur
Formatierung von Texten oder Ausgaben verwendet.
Beispiel 2.39
Es ist folgender String gegeben :
" abcd " , Stringlänge ist 4
Liegt eine ASCII-Kodierung vor, dann wird die Zeichenkette als Folge von 4 ganzen Zahlen
(7-Bit Zahlen), entsprechend der ACSII-Codierung abgespeichert:
97,98,99,100 (Darstellung als Dezimalzahl)
40
Layout
bs
ht
lf
vt
ff
cr
2. Die Programmiersprache Perl
Characters:
backspace
horizontal Tabulation
linefeed
vertical tabulation
form feed
carriage return
Escape Characters:
so
shift-out
si
shift-in
esc
escape
Medium Characters:
bel
bell ring
dc1-dc4
device controll
em
end of medium
Ignore characters:
nul
null character
can
cancel
sub
substiute
del
delete
Communication Characters:
soh
start of heading
stx
start of text
etx
end of text
eot
end of transmission
enq
enquiry
ack
acknowledgement
nak
negative acknowledgement
dle
data link escape
syn
synchronous idle
etb
end of transmission block
Seperator characters:
fs
fileseperator
gs
group seperator
rs
record seperator
us
unit seperator
Tabelle 2.8.: Bedeutung der Steuerzeichen
2.13.5. Zeichencodierung: ISO Latin-1 für Buchstaben, 8 Bit
Für länderspezifische Buchstaben fand sich im ASCII-Code kein Zeichencode mehr. Versuche, den ASCII-Code auf 8 Bit zu erweitern, scheiterten daran, dass kein gemeinsamer
Standard für die Buchstabennummern gefunden wurde. Erst der ISO (=International
Standardization Organization) gelang es den Buchstabencode auf 8 Bit zu erweitern und
länderspezifische Buchstaben zu standardisieren. Die ISO definierte für verschieden Sprachfamilien verschiedene Zeichenkodierungen. Für die lateinischen Buchstaben definierten
sie z.B. ISO-LATIN. Um auch Buchstaben zu kodieren, die nicht lateinisch sind, wurden
von der ISO weitere länderspezifische Zeichencodes entwickelt, z.B. für die griechischen
Buchstaben ISO-Greek.
Die folgende Tabelle zeigt die Definitionen des ISO-Latin-1 Character Set oder auch ISO8859-1.
Description
==================
quotation mark
ampersand
less-than sign
greater-than sign
Description
==================
non-breaking space
inverted exclamation
cent sign
pound sterling
Char
====
¡
¢
£
Code
==========
&#34; → "
&#38; → &
&#60; → <
&#62; → >
Entity name
============
&quot; → "
&amp; → &
&lt; → <
&gt; → >
Code
============
&#160;→
&#161; → ¡
&#162; → ¢
&#163; → £
Entity name
============
&nbsp; →
&iexcl; → ¡
&cent; → ¢
&pound; → £
2.13. Interne Repräsentation von Schriftzeichen
41
general currency sign
yen sign
broken vertical bar
¤
¥
¦
&#164; → ¤
&#165; → ¥
&#166; → ¦
section sign
umlaut (dieresis)
§
¨
&#167; → §
&#168; → ¨
copyright
feminine ordinal
left angle quote, guillemotleft
not sign
soft hyphen
registered trademark
macron accent
©
ª
«
¬
®
¯
&#169;
&#170;
&#171;
&#172;
&#173;
&#174;
&#175;
→©
→ª
→«
→¬
→
→®
→¯
degree sign
plus or minus
superscript two
superscript three
acute accent
micro sign
paragraph sign
middle dot
cedilla
superscript one
masculine ordinal
right angle quote, guillemotright
fraction one-fourth
fraction one-half
fraction three-fourths
inverted question mark
capital A, grave accent
capital A, acute accent
capital A, circumflex accent
capital A, tilde
capital A, dieresis or umlaut mark
capital A, ring
capital AE diphthong (ligature)
capital C, cedilla
capital E, grave accent
capital E, acute accent
capital E, circumflex accent
capital E, dieresis or umlaut mark
capital I, grave accent
capital I, acute accent
capital I, circumflex accent
capital I, dieresis or umlaut mark
capital Eth, Icelandic
°
±
2
3
´
µ
¶
·
¸
1
º
»
¼
½
¾
¿
À
Á
Â
Ã
Ä
Å
Æ
Ç
È
É
Ê
Ë
Ì
Í
Î
Ï
Ð
&#176;
&#177;
&#178;
&#179;
&#180;
&#181;
&#182;
&#183;
&#184;
&#185;
&#186;
&#187;
&#188;
&#189;
&#190;
&#191;
&#192;
&#193;
&#194;
&#195;
&#196;
&#197;
&#198;
&#199;
&#200;
&#201;
&#202;
&#203;
&#204;
&#205;
&#206;
&#207;
&#208;
→°
→±
→2
→3
→´
→µ
→¶
→·
→¸
→1
→º
→»
→¼
→½
→¾
→¿
→À
→Á
→Â
→Ã
→Ä
→Å
→Æ
→Ç
→È
→É
→Ê
→Ë
→Ì
→Í
→Î
→Ï
→Ð
capital N, tilde
capital O, grave accent
Ñ
Ò
&#209; → Ñ
&#210; → Ò
&curren; → ¤
&yen; → ¥
&brvbar; → ¦
&brkbar; → &brkbar;
&sect; → §
&uml; → ¨
&die; → &die;
&copy; → ©
&ordf; → ª
&laquo; → «
&not; → ¬
&shy; →
&reg; → ®
&macr; → ¯
&hibar; → &hibar;
&deg; → °
&plusmn; → ±
&sup2; → 2
&sup3; → 3
&acute; → ´
&micro; → µ
&para; → ¶
&middot; → ·
&cedil; → ¸
&sup1; → 1
&ordm; → º
&raquo; → »
&frac14; → ¼
&frac12; → ½
&frac34; → ¾
&iquest; → ¿
&Agrave; → À
&Aacute; → Á
&Acirc; → Â
&Atilde; → Ã
&Auml; → Ä
&Aring; → Å
&AElig; → Æ
&Ccedil; → Ç
&Egrave; → È
&Eacute; → É
&Ecirc; → Ê
&Euml; → Ë
&Igrave; → Ì
&Iacute; → Í
&Icirc; → Î
&Iuml; → Ï
&ETH; → Ð
&Dstrok; → &Dstrok;
&Ntilde; → Ñ
&Ograve; → Ò
42
2. Die Programmiersprache Perl
capital O, acute accent
capital O, circumflex accent
capital O, tilde
capital O, dieresis or umlaut mark
multiply sign
capital O, slash
capital U, grave accent
capital U, acute accent
capital U, circumflex accent
capital U, dieresis or umlaut mark
capital Y, acute accent
capital THORN, Icelandic
small sharp s, German (sz ligature)
small a, grave accent
small a, acute accent
small a, circumflex accent
small a, tilde
small a, dieresis or umlaut mark
small a, ring
small ae diphthong (ligature)
small c, cedilla
small e, grave accent
small e, acute accent
small e, circumflex accent
small e, dieresis or umlaut mark
small i, grave accent
small i, acute accent
small i, circumflex accent
small i, dieresis or umlaut mark
small eth, Icelandic
small n, tilde
small o, grave accent
small o, acute accent
small o, circumflex accent
small o, tilde
small o, dieresis or umlaut mark
division sign
small o, slash
small u, grave accent
small u, acute accent
small u, circumflex accent
small u, dieresis or umlaut mark
small y, acute accent
small thorn, Icelandic
mall y, dieresis or umlaut mark
Ó
Ô
Õ
Ö
×
Ø
Ù
Ú
Û
Ü
Ý
Þ
ß
à
á
â
ã
ä
å
æ
ç
è
é
ê
ë
ì
í
î
ï
ð
ñ
ò
ó
ô
õ
ö
÷
ø
ù
ú
û
ü
ý
þ
ÿ
&#211;
&#212;
&#213;
&#214;
&#215;
&#216;
&#217;
&#218;
&#219;
&#220;
&#221;
&#222;
&#223;
&#224;
&#225;
&#226;
&#227;
&#228;
&#229;
&#230;
&#231;
&#232;
&#233;
&#234;
&#235;
&#236;
&#237;
&#238;
&#239;
&#240;
&#241;
&#242;
&#243;
&#244;
&#245;
&#246;
&#247;
&#248;
&#249;
&#250;
&#251;
&#252;
&#253;
&#254;
&#255;
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
→
Ó
Ô
Õ
Ö
×
Ø
Ù
Ú
Û
Ü
Ý
Þ
ß
à
á
â
ã
ä
å
æ
ç
è
é
ê
ë
ì
í
î
ï
ð
ñ
ò
ó
ô
õ
ö
÷
ø
ù
ú
û
ü
ý
þ
ÿ
&Oacute; → Ó
&Ocirc; → Ô
&Otilde; → Õ
&Ouml; → Ö
&times; → ×
&Oslash; → Ø
&Ugrave; → Ù
&Uacute; → Ú
&Ucirc; → Û
&Uuml; → Ü
&Yacute; → Ý
&THORN; → Þ
&szlig; → ß
&agrave; → à
&aacute; → á
&acirc; → â
&atilde; → ã
&auml; → ä
&aring; → å
&aelig; → æ
&ccedil; → ç
&egrave; → è
&eacute; → é
&ecirc; → ê
&euml; → ë
&igrave; → ì
&iacute; → í
&icirc; → î
&iuml; → ï
&eth; → ð
&ntilde; → ñ
&ograve; → ò
&oacute; → ó
&ocirc; → ô
&otilde; → õ
&ouml; → ö
&divide; → ÷
&oslash; → ø
&ugrave; → ù
&uacute; → ú
&ucirc; → û
&uuml; → ü
&yacute; → ý
&thorn; → þ
&yuml; → ÿ
Tabelle 2.9.: Definitionen des ISO-Latin-1 Character Set
2.13. Interne Repräsentation von Schriftzeichen
43
Lesen der Tabelle:
1. Spalte:
2. Spalte:
3. Spalte:
4. Spalte:
Textliche Beschreibung des Buchstaben
Darstellung des Buchstabes
Buchstabencode wie er in HTML Texten als numerischer Entity geschrieben
werden kann
Buchstabencode wie er in HTML Texten als symbolischer Entity geschrieben
werden kann
Die Tabelle wurde entnommen von:
Martin Ramsch’s „ISO 8859-1 Table“
Copyright:
©International Organization for Standardization 1986. Permission to copy in any form is granted
for use with conforming SGML systems and applications as defined in ISO 8879, provided this
notice is included in all copies.
2.13.6. Zeichenkodierung nach den Vorgaben des UNICODE Konsortium
Der große Nachteil der ISO-Standardisierung ist, dass ähnlich wie bei ASCII nur einem
Teil der sinntragenden Schriftzeichen bzw. Textelemente aller bekannten Schriftkulturen
und Zeichensysteme ein Zahlencode zugeordnet wurde. Außerdem gab es bei den Zeichencodes keine Eindeutigkeit, da die Zuordnung des Zahlencodes zum Schriftzeichen von der
eingestellten Sprachfamilie abhängig war:
Zahlencode
(Hexadezimal)
C4
ISO Codierung
ISO-Greek
ISO-Latin
∆ (Delta)
Ä (Umlaut Ä)
Tabelle 2.10.: ISO Codierung
Die Ambiguität löste das UNICODE Konsortium, indem es einen Universal Character Set
(UCS) definierte. Der UCS reserviert für 1.114.112 Schriftzeichen Zeichencodes. Sie sollen
für alle Schriftzeichen aller bekannten Schriftkulturen ausreichen. Die Bitbreite für die
Zeichencodes wurde von 8 Bit auf 32 Bit erweitert. Sie definierten eine UNICODE Tabelle,
in der jedem Schriftzeichen ein eindeutiger Zeichencode zugeordnet wurde:
UNICODE Codierung
Zahlencode (Hexadezimal) Zeichen
41
A
42
B
C4
Ä (Umlaut Ä)
3FF
∆ (griechisches Delta)
22FF
∆ (mathematisches Delta)
c39e
þ(Grossbuchstabe ”Thorn”)
Tabelle 2.11.: UNICODE Codierung
Würde jetzt ein Text mit den vier Zeichen „ABBA“ abgespeichert, so wäre dies unter
UNICODE mit der Folge von vier 32 Bit Zahlen realisiert:
0
0
0
0
0
0
0
0
0
0
0
0
41
42
42
41
44
2. Die Programmiersprache Perl
Wir hätten also 4·4 Bytes = 16 Bytes in der Datei. Betrachtet man die 16 Bytes der
Zeichencodes, so sieht man, dass nur 4 Bytes Informationen tragen, die anderen 12 Bytes
sind Nullbytes. Als C-Programmierer weiß man, welche Probleme die Zahl Null in einem
bytestream verursachen kann (Stichwort: File/ Stringende). Außerdem kann man auch
von einer Platzverschwendung sprechen, da nur 4 Bytes die Information der Zeichencodes
tragen. Daraufhin entwickelte Ken Thompson von den BELL Laboratories ein Transformationsformat, das in eindeutiger Weise die Zahlenfolge repräsentiert, aber nur die Bytes
speichert, die die Informationen für die Zeichencodes tragen. Auf die Nullbytes verzichtet
sein Verfahren. Das UNICODE – Konsortium übernahm dieses Verfahren und legte für
jedes Schriftzeichen eine eindeutige Folge von Zahlen fest. Ein mitgelieferter Transformationsalgorithmus kann aus dieser Folge die eindeutige UNICODE-Zahl des zugrunde
gelegten Schriftzeichens berechnen. Diese Kodierung nannten Sie „multibyte-Kodierung“.
Aus „ABBA“ wurde wieder die Folge der 4 Bytes: 41 42 42 41
2.13.7. Die UTF Prinzipien
Das UNICODE – Transformation Format (UTF) weist jedem Schriftzeichen eine eindeutige
Folge von Zahlen zu, deren Bitbreite das Appendix „-n“ ausdrückt:
UTF -6 ... eine Folge von 6 - Bit Zahlen
UTF -8 ... eine Folge von 8 - Bit Zahlen (1 Byte )
UTF -16 ... eine Folge von 16 - Bit Zahlen (2 Bytes )
UTF -32 ... eine Folge von 32 - Bit Zahlen (4 Bytes )
Kennt der Transformations Algorithmus die Bitbreite der zugrundegelegten Codierung,
dann kann er die eindeutige UNICODE-Nummer mit Hilfe von Bitoperationen sehr effizient
berechnen (siehe nächstes Kapitel 3)
Schriftzeichen
A
Ä
∆
UNICODE Nummer
(Hexadezimal)
41
C4
394
utf-8 Byte Folge
(Hexadezimal)
41
C3 84
CE 94
Der Text aus den drei Zeichen A, Ä und Delta ∆ : „AÄ∆“ wäre bei UTF-8 mit folgender
Bytefolge abgespeichert:
41 C3 84 CE 94
Wie der Transformations-Algorithmus aus dieser Folge die Zeichennummer 41,C4 und 394
errechnet, wird im nächsten Kapitel erklärt.
2.13.8. Die UTF Kodierung im Detail
aus http://de.wikipedia.org/wiki/UTF-8
(Abk. für 8-bit Unicode Transformation Format)
ist die fortschrittlichste und populärste Kodierung für Unicode-Zeichen; dabei wird jedem
Unicode-Zeichen eine speziell kodierte Bytekette von variabler Länge zugeordnet. Es
unterstützt bis zu 4 Byte auf die sich wie bei allen UTF Formaten alle 1.114.112 Unicode
Zeichen abbilden lassen. UTF-8 ist gegenwärtig als Request for Comments RFC 3629
standardisiert (UTF-8, a transformation format of ISO 10646). Dieser Standard löst das
ältere RFC 2279 ab. Unicode-Zeichen mit den Werten aus dem Bereich von 0 bis 127
(0 bis 7F hexadezimal) werden in der UTF-8-Kodierung als ein Byte mit dem gleichen
Wert wiedergegeben. Insofern sind alle Daten, die ausschließlich echte ASCII-Zeichen
verwenden, in beiden Darstellungen identisch. Unicode-Zeichen größer als 127 werden in
der UTF-8-Kodierung zu Byteketten der Länge zwei bis vier.
2.13. Interne Repräsentation von Schriftzeichen
UnicodeBereich
45
UTF-8 Ko- Bemerkungen
dierung
0000 0000 - 0xxxxxxx
0000 007F
Möglichkeiten
In diesem Bereich (128 Zei- 27
chen) entspricht UTF-8 genau
dem ASCII-Code: Das erste
Bit ist 0, die darauf folgende 7Bitkombination ist das ASCIIZeichen.
0000 0800 - 1110xxxx
0000 FFFF 10xxxxxx
10xxxxxx
Das erste Byte beginnt mit
binär 11, die folgenden Bytes
beginnen mit binär 10; die x
stehen für die fortlaufende
Bitkombination des
Unicodezeichens. Die Anzahl
der Einsen bis zur ersten 0 im
ersten Byte
0001 0000 0010 FFFF
[0001 0000 001F FFFF]
ist die Anzahl der Bytes für 220
das Zeichen. [In eckigen Klammern jeweils die theoretisch
maximal möglichen.]
0000 0080 - 110xxxxx
0000 07FF
10xxxxxx
11110xxx
10xxxxxx
10xxxxxx
10xxxxxx
128
211 − 27
216 − 211
[221 ]
[211 ]
[216 ]
1.920
[2.048]
63.488
[65.536]
1.048.576
[2.097.152]
Tabelle 2.12.: Die UTF Kodierung im Detail
Der Algorithmus lässt theoretisch mehrere Billionen Zeichen zu (27×6 +26×6+1 +25×6+2 +. . .),
die aktuelle RFC beschränkt diese jedoch auf die durch UTF-16 erreichbaren, also bis
0010 FFFF (1.114.111). Das erste Byte eines UTF-8-kodierten Zeichens nennt man dabei
Start-Byte, weitere Bytes nennt man Folgebytes. Startbytes beginnen also mit der Bitfolge
11 oder einem 0-Bit, während Folgebytes immer mit der Bitfolge 10 beginnen.
Betrachtet man die Bitfolgen etwas genauer, erkennt man die große Sinnfälligkeit von
UTF-8:
Ist das höchste Bit des ersten Byte 0, handelt es sich um ein gewöhnliches ASCII-Zeichen, da
ASCII eine 7-Bit-Kodierung ist und die ersten 128 Zeichen des Unicode die ASCII-Zeichen
sind. Damit sind alle ASCII-Dokumente automatisch aufwärtskompatibel zu UTF-8.
Ist das höchste Bit des ersten Byte 1, handelt es sich um ein Mehrbytezeichen, also ein
Unicode-Zeichen mit einer Zeichennummer größer als 127.
Sind die höchsten beiden Bits des ersten Byte 11, handelt es sich um das Start-Byte eines
Mehrbytezeichens, sind sie 10, um ein Folge-Byte.
Die lexikalische Ordnung nach Byte-Werten entspricht der lexikalischen Ordnung nach
Buchstaben-Nummern, da größere Zeichennummern mit entsprechend mehr 1-Bits am
Anfang kodiert werden.
Bei den Start-Bytes von Mehrbyte-Zeichen gibt die Anzahl der 1-Bits vor dem ersten
0-Bit die gesamte Bytezahl des als Mehrbyte-Zeichen kodierten Unicode-Zeichens an.
Anders interpretiert, die Anzahl der 1-Bits vor dem ersten 0-Bit nach dem ersten Bit
entspricht der Anzahl an Folgebytes, z.B. 1110xxxx 10xxxxxx 10xxxxxx 3 Bits vor dem
ersten 0-Bit = 3 Bytes insgesamt, 2 Bits vor dem ersten 0-Bit nach dem ersten 1-Bit = 2
46
2. Die Programmiersprache Perl
Folgebytes. Start-Bytes (0xxx xxxx oder 11xx xxxx) und Folge-Bytes (10xx xxxx) lassen
sich eindeutig voneinander unterscheiden. Somit kann ein Byte-Strom auch in der Mitte
gelesen werden, ohne dass es Probleme mit der Dekodierung gibt, was insbesondere bei der
Wiederherstellung defekter Daten wichtig ist. Bytes, die mit 10 beginnen, werden einfach
übersprungen, bis ein Byte gefunden wird, das mit 0 oder 11 beginnt. Könnten Start-Bytes
und Folge-Bytes nicht eindeutig voneinander unterschieden werden, wäre das Lesen eines
UTF-8-Datenstroms, dessen Beginn unbekannt ist, unter Umständen nicht möglich.
Zu beachten:
Das gleiche Zeichen kann theoretisch auf verschiedene Weise kodiert werden. Jedoch ist
nur die jeweils kürzeste mögliche Kodierung erlaubt.
Bei mehreren Bytes für ein Zeichen werden die Bits rechtsbündig angeordnet - das rechte
Bit des Unicode Zeichens steht also immer im rechten Bit des letzten UTF-8 Bytes.
Ursprünglich gab es auch Kodierungen mit mehr als 4 Oktetts (bis zu 6), diese sind jedoch
ausgeschlossen worden, da es in Unicode keine korrespondierenden Zeichen gibt und ISO
10646 in seinem möglichen Zeichenumfang an Unicode angeglichen wurde.
Für alle auf dem Lateinischen Alphabet basierten Schriften, ist UTF-8 die platzsparendste
Methode zur Abbildung von Unicode Zeichen.
UTF-8, UTF-16 und UTF-32 kodieren alle den vollen Wertebereich von Unicode.
2.13.9. UTF-8 im Internet
Im Internet wird immer häufiger die UTF-8 Kodierung verwendet. So unterstützt auch
Wikipedia alle denkbaren Sprachen. Möglich macht all das ein Meta-Tag im Kopf der
Webseite:
< meta http - equiv =" Content - Type " content =" text / html ; charset = utf -8" / >
Auch in eMails ist bei einigen Programmen schon die UTF-8 Kodierung voreingestellt.
Sie stellt sicher, dass auch Sonderzeichen unterschiedlicher Länder richtig übertragen und
dargestellt werden. Siehe auch: UTF-7, UTF-16, UTF-32, Unicode
2.13.10. UTF-8 Mode in Perl
Bei den Perl-Releases vor 5.6 wurden alle Strings als Bytesequenzen betrachtet. Seit der
Version 5.6 kann ein String aber nun auch Zeichen enthalten, die mehr als ein Byte
benötigen. Bei der Verwendung von Unicode muss man sich keine Gedanken mehr darum
machen, wie viele Bits oder Bytes die Repräsentation eines Zeichens verlangt. Perl gibt
nur vor, dass alle Unicode-Zeichen die gleiche Länge (d.h. die Länge 1) aufweisen, auch
wenn ein Zeichen intern durch mehrere Bytes repräsentiert werden kann. Perl repräsentiert
Unicode normalerweise in Form von UTF-8, einer Codierung variabler Länge.
Perl kann also schon von sich aus mit Unicode und UTF-8 umgehen. Um nun in einem
Unicode-fähigen Editor diese Zeichen innerhalb eines literalen Strings direkt als UTF8-Zeichen erscheinen zu lassen, muss man zu Beginn des Programms "use utf8" bzw.
"use encoding 'utf8'" deklarieren. Dann sind alphanumerische Unicode-Sonderzeichen in
Variablen- und Routinennamen sowie in Strings zulässig.
2.13. Interne Repräsentation von Schriftzeichen
47
Beispiel 2.40: Anwendung von "use utf8"
Hat man keinen Editor mit dem Unicodetext verarbeitet werden kann, so gibt es die
Möglichkeit, ein bestimmtes Unicodezeichen als ASCII-Zeichenkette anzugeben. Die ASCIIZeichenkette beginnt mit der Zeichenfolge \x, gefolgt von der Hexadezimalnummer des
UNICODE Zeichens. Die Nummer muss in geschweiften Klammern eingeschlossen werden.
So könnte man anstatt des kyrillischen Buchstabens auch Zeichenfolge
\ x {043 B }
schreiben. Den in Beispiel 1 genannten Text könnte man auch als
Ich bin die kyrillische Variable \ x {043 F } er \ x {043 B };
schreiben.
Bei regulären Ausdrücken ist zu beachten, dass der Punkt in der Unicode-Umgebung auf
ein Zeichen passt, nicht mehr auf ein Byte. Dasselbe gilt für Zeichenklassen wie \w und \s.
Ähnliche Änderungen ergeben sich unter anderem auch für Funktionen wie length(), die
erwartungsgemäß nicht mehr Bytes sondern Zeichen verarbeiten.
Beispiel 2.41: Vergleich zweier Unicode-Zeichenketten
#!/ usr / bin / perl
# Vergleich zweier Unicode - Zeichenketten
use strict ;
use utf8 ;
{
my $smiley1 = "?";
my $smiley2 = "\ x {263 A }"; # Schreibweise als ASCII - Zeichenfolge
}
print " $smiley1 \ n ";
print " $smiley2 \ n ";
if ( $smiley1 eq $smiley2 ) {
print " Smileys sind gleich \ n ";
} else {
print " Smileys sind nicht gleich \ n ";
}
Ohne use utf8 würden die beiden Smileys nicht als identisch identifiziert werden.
Berücksichtigung spezifischer internationaler Eigenheiten von Buchstaben:
In verschiedenen Sprachkulturen können sich die Eigenschaften von Buchstaben unterscheiden, manche Buchstaben gibt es nur in einzelnen Sprachen. Im Englischen gibt es z.B.
keine Umlaute. Damit die Eigenschaften von Buchstaben entsprechend ihrer Sprachkultur
in einem Programm berücksichtigt werden, müssen in Perl Programmen die sogenannten
locale – Einstellungen aktiviert werden. Standardmäßig werden die locale-Einstellungen von
Perl ignoriert. Die Aktivierung der sprachspezifischen Eigenschaften von Buchstaben wird
mit der Deklaration use locale realisiert und betrifft folgende Operationen und Funktionen
im Programm:
48
2. Die Programmiersprache Perl
• die Vergleichsoperatoren (lt, le, cmp, ge, gt) sowie die POSIX-Zeichenklassen (z. B.
[:alnum:] oder [:alpha:]).
• indirekt die Funktion sort, da sie den Vergleichsoperator cmp verwendet
• reguläre Ausdrücke und String-modifizierende Funktionen wie uc(), lc()
• formatierende Funktionen wie printf() oder write()
Das folgende Beispiel zeigt, wie Wörter in Perl von der Routine sort alphabetisch sortiert
werden können. Je nachdem welche nationale locale-Einstellung vorgenommen wird, werden
die Umlaute unterschiedlich in das Alphabet einsortiert. Ohne Verwendung der Anweisung use locale wird die Standardcodierung ASCII verwendet. Der Aufruf der Anweisung
use locale stellt das Programm ab dieser Stelle auf die selbe Kodierung wie die Konsole,
von der das Perl Programm aufgerufen wurde.
• standard locale (ASCII Codierung): Die Umlaute kommen nach dem Buchstaben Z
• deutsches locale: Die Umlaute werden entsprechend Ihrem ae, ue bzw. oe einsortiert.
Beispiel 2.42: Auswirkungen von use locale auf sort
#!/ usr / bin / perl
# Demonstration der Auswirkung von use locale auf sort
use strict ;
my ( @woerter , @ascii_sortiert , @deu_sortiert );
{
@woerter = qw ( der älteste amerikaner öffnete zehn mal den ofen );
# qw bedeutet : Quote Words und erzeugt die Liste :
# @woerter =
#
(" der " , älteste " ," amerikaner " ," öffnete " ," zehn " ," mal " ," den " ," ofen ");
@ascii_sortiert = sort @woerter ; # Standardcodierung ASCII
print " ASCII : " , join ( ' , ', @ascii_sortiert ) ,"\ n ";
{
}
}
use locale ;
# Codierung auf die Kodierung der Console setzen
@deu_sortiert = sort @woerter ;
print " Deutsches Locale : " , join ( ' , ', @deu_sortiert ) ,"\ n ";
Ergebnis :
ASCII : amerikaner , den , der , mal , ofen , zehn , älteste , öffnete
Deutsches Locale : älteste , amerikaner , den , der , mal , öffnete , ofen , zehn
2.14. Lesen der Daten vom Terminal mit utf8 Kodierung
Wie im vorherigen Kapitel erwähnt, werden in Perl Zeichen, die nicht zu den ASCII Zeichen
gehören, nur dann richtig eingelesen bzw. ausgegeben, wenn das Perl – Programm auf die
Kodierung des Konsolenterminals eingestellt ist, von dem das Perl Programm gestartet
wurde. Da die Standardkodierung eines LINUX Konsolenterminals auf utf-8 eingestellt ist,
muss das Perl Programm die internen Standardkanäle der Eingabe (<STDIN>) und Ausgabe
(<STDOUT>) ebenfalls auf utf-8 setzen. Der Programmierer hat dafür zwei Möglichkeiten.
2.14. Lesen der Daten vom Terminal mit utf8 Kodierung
49
2.14.1. Standardein- und ausgabe beim Programmstart auf utf8 festlegen
Der Programmierer kann beim Programmstart explizit festlegen, dass die Standardkanäle
und <STDOUT> den UNICODE Zeichensatz und die UTF-8 Codierung produzieren,
bzw. erwarten. Er muss beim Start des Perl Programms das Perl Kommando mit der
Option -C aufrufen.
<STDIN>
Beispiel 2.43: Setzen von STDIN und STDOUT auf utf-8 beim Programmstart
Start des Programms:
perl -C my_utf8 . perl
Das Programm dazu:
#!/ usr / bin / perl
# Setzen von STDIN und STDOUT auf utf -8 beim Programmstart
use strict ;
{
my $line ;
}
while ( $line = < >) {
chomp ( $line );
if ( $line =~ /[ äüö ]/) { # siehe Kapitel Reguläre Ausdrücke
print " Umlaut gefunden $line \ n ";
}
}
2.14.2. Standardein- und ausgabe zur Laufzeit auf utf8 festlegen
Möchte der Programmierer nicht beim Progammstart festlegen, dass die Standardkanäle
und <STDOUT> den UNICODE Zeichensatz und die UTF-8 Codierung produzieren,
bzw. erwarten, dann kann er dies auch innerhalb des Programms, also zur Laufzeit des
Programms erreichen. Dazu gibt es die spezielle Perl-Routine binmode, die im Programm
aufgerufen wird:
Perl-Routine :
<STDIN>
binmode ( Kanal , Kodierung )
Dazu das Programm:
#!/ usr / bin / perl -w
# Setzen von STDIN STDOUT und STDERR im Programm
use strict ;
{
binmode ( STDIN ,": utf8 ");
binmode ( STDOUT ,": utf8 ");
binmode ( STDERR ,": utf8 ");
my $line ;
}
while ( $line = < >) {
print $line ;
}
Die Perl Funktion binmode schaltet die im ersten Argument aufgelisteten Kanäle (hier
STDIN, STDOUT und STDERR) auf utf8 um.
Start des Programms:
perl my_utf8_im_programm . perl
50
2. Die Programmiersprache Perl
2.14.3. Lesen aus Dateien mit utf-8 Kodierung
Um mit Perl UTF-8 kodierte Unicode Dateien zu lesen gibt es zwei Möglichkeiten: Entweder
werden alle open Befehle mit use open ":utf8" auf utf8 gesetzt oder die open Anweisung
wird mit drei Argumenten aufgerufen:
open ( filehandle , Öffnungsmodus , Dateiname )
filehandle : Name des Filehandles,
Öffnungsmodus: Lesen, Schreiben, Anhängen, inklusiv uft-8 Markierung
Dateiname: der Name der Datei
Beispiel 2.44: Alle Dateien sind utf-8 Dateien. Open Befehl mit 2 Argumenten
#!/ usr / bin / perl -w
# file :/ DieSprache / useOpen2 . perl
# Setzen von STDOUT und STDIN auf utf -8
use strict ;
use utf8 ;
# Erlaubt Umlaute in Variablennamen
use locale ;
# Sortiert nach Deutschen Regeln
use open ": utf8 ";
# Alle Dateien sind utf -8 Dateien
{
my ( $wort , @woerter , @sorted_woerter );
binmode ( STDIN , ": utf8 " );
# Setzt STDIN auf utf -8
binmode ( STDOUT , ": utf8 " );
# Setzt STDOUT auf utf -8
open ( INP ,
" abc . txt " );
open ( OUT ,
" > abc_out . txt " );
open ( OUTSORTED , " > abc_sorted . txt " );
while ( $wort = <INP > ) {
chomp ( $wort );
print " $wort \ n ";
print OUT " $wort \ n ";
push ( @woerter , $wort );
}
close INP ;
@sorted_woerter = sort @woerter ;
print " Sortiert nach deutschen Regeln : \ n " , join ( ', ', @sorted_woerter ) ,
"\ n ";
print OUTSORTED " Sortiert nach deutschen Regeln : \ n " ,
join ( ', ', @sorted_woerter ) , "\ n ";
}
close OUT ;
close OUTSORTED ;
Beispiel 2.45: Dateikodierung wird einzeln definiert. Open Befehl mit 3 Argumenten
#!/ usr / bin / perl -w
# file :/ DieSprache / useOpen3 . perl
# Einlesen und Ausgeben mit utf -8
use strict ;
use utf8 ;
use locale ;
{
# Erlaubt Umlaute in Variablennamen
# Sortiert nach Deutschen Regeln
my ( $wort , @woerter , @sorted_woerter );
binmode ( STDIN ,": utf8 ");
binmode ( STDOUT ,": utf8 ");
2.15. Die spezielle Variable : $_
51
open ( INP ," <: utf8 " ," abc . txt ");
# die Datei abc . txt ist eine utf -8 Datei
open ( OUT ," >: utf8 " ," abc_out . txt "); # die Datei abc_out . txt ist
# eine utf -8 Datei
open ( OUTSORTED ," >: utf8 " ," abc_sorted . txt ");
}
while ( $wort = < INP >) {
chomp ( $wort );
print " $wort \ n ";
print OUT " $wort \ n ";
push ( @woerter , $wort );
}
close INP ;
@sorted_woerter = sort @woerter ;
print " Sortiert nach deutschem Locale : \ n " , join ( ' ,
', @sorted_woerter ) ,"\ n ";
print OUTSORTED " Sortiert nach deutschen Regeln : \ n " , join ( ' ,
', @sorted_woerter ) ,"\ n ";
close OUT ;
close OUTSORTED ;
2.15. Die spezielle Variable : $_
Die Variable $_ ist eine in Perl intern vordefinierte skalare Variable. Sie gehört zur Gruppe
der „Special Variables“ und ist davon die am häufigsten verwendete. Die Variable bekommt
bei bestimmten Perl-Anweisungen automatisch einen Wert zugewiesen, bei anderen PerlAnweisungen wird der aktuelle Wert der Variablen verwendet. So speichert z. B. der
Einleseoperator den eingelesenen Wert in der Variablen $_, wenn keine explizite Zuweisung
zu einer Variablen vor dem Operator steht. Die print Anweisung ohne Variable gibt z. B.
den Wert der Variablen $_ aus.
Beispiel 2.46: Einlesen und Ausgeben der Standardeingabe
anstatt:
#!/ usr / bin / perl
# Einlesen und Ausgeben mit Diamondoperator
use strict ;
{
my $line ;
while ( $line = < >) {
print $line ;
}
}
kann man unter impliziter Verwendung der Special Variable $_ auch schreiben:
#!/ usr / bin / perl
# Einlesen und Ausgeben mit Special Variable
use strict ;
{
while ( < >) {
print ;
}
}
Erklärung: Da bei der Einleseoperation <> die Zuweisung an eine Variable fehlt, speichert
Perl den Wert der eingelesenen Zeile automatisch in der Special Variable $_. Da nach der
print-Anweisung keine Variable folgt, nimmt Perl den Wert, der in $_ gespeichert ist und
druckt ihn aus.
52
2. Die Programmiersprache Perl
Beispiel 2.47: Spezielle Variable in der foreach-Schleife
anstatt:
#!/ usr / bin / perl
# Demonstration der foreach - Anweisung
use strict ;
{
my $zahl ;
foreach $zahl (1..10) {
print $zahl ;
print "\ n ";
}
}
kann man unter impliziter Verwendung der Special Variable $_ auch schreiben:
#!/ usr / bin / perl
# foreach - Anweisung mit Special Variable
use strict ;
{
foreach (1..10) {
print ;
print "\ n ";
}
}
Auch hier fehlt eine Variable um den Wert des Elements bei einem Schleifendurchlauf zu
speichern, es wird der Schleifenwert in der Variable $_ gespeichert, bzw. von print ohne
Argument ausgegeben.
Beispiel 2.48: If-Varianten mit der speziellen Variablen
Anstatt der braven Variante:
#!/ usr / bin / perl
# Demonstration der If - Abfrage
use strict ;
{
while ( $line = < >) {
if ( $line =~ / ist /) {
print $line ;
}
}
}
kann man unter impliziter Verwendung der Special Variable $_ auch schreiben:
#!/ usr / bin / perl
# If - Abfrage mit Special Variable
use strict ;
{
while ( < >) {
if (/ ist /) {
print ;
}
}
}
2.16. Datenstrukturen 2: Hashes
53
Noch kürzer geht es mit dem Conditional Statement:
#!/ usr / bin / perl
# If - Abfrage mit Special Variable und Conditional Statement
use strict ;
{
while ( < >) {
print if (/ ist /);
}
}
2.16. Datenstrukturen 2: Hashes
Neben der Möglichkeit Elemente in Listen zu speichern und über Indizes auf sie zuzugreifen,
gibt es in Perl die Möglichkeit, Elemente in sogenannten Hashes abzuspeichern. Bei Hashes
hat man die Möglichkeit den Schlüssel, mit dem man auf die Elemente zugreift, selbst
festzulegen.
Die Schlüssel, mit denen man bei Hashes auf die Elemente zugreift, nennt man key, den
Wert, der unter einem Key definiert ist, nennt man value. Wenn man einen Hash als Ganzes
benutzen möchte, benutzt man das % Zeichen. z.B. %namen, wenn man auf einzelne Elemente
zugreifen möchte ähnelt das dem Zugriff auf Array Elemente, nur dass man statt der
eckigen Klammern z.B.
$werte [5] = 300;
geschweifte Klammern verwendet, z.B.
$namen {" Meier "}
=
4;
Bei diesem Beispiel ist "Meier" der key, 4 der value. Somit bilden Hashes eine sehr gute
Möglichkeit Wortlisten, die die Häufigkeit von Wörtern in einem Text zählen, zu erzeugen.
Beispiel 2.49: Wörter einlesen, in den Hash übertragen (keys) und die Häufigkeit der einzelnen
Wörter zählen (values)
#!/ usr / bin / perl -w
# Erstellen einer Frequenzliste mithilfe von Hash
use strict ;
{
my % lexikon ;
my ( $wort , $datei );
print (" Bitte geben Sie den Namen einer Datei ein :\ n ");
$datei = < >;
open ( DATEI , $datei );
}
while ( $wort = < DATEI >) {
chomp $wort ;
if ( defined $lexikon { $wort }) {
$lexikon { $wort }++;
} else {
$lexikon { $wort } = 1;
}
}
close DATEI ;
54
2. Die Programmiersprache Perl
Zugriff und Ausdrucken des Elements, gespeichert unter dem Key "ich":
print (" $lexikon { ' ich '}\ n ");
(Achtung mit dem Einsatz der Hochkommas!)
Erzeugen eines neuen Elements eines Hashes:
$lexikon { ' wir '} = 3;
Erhöhen des Wertes eines Eintrags in einem Hash, der unter einem bestimmten Key
gespeichert ist:
$lexikon { ' wir '} = $lexikon { ' wir '} + 1;
oder
$lexikon { ' wir '}++;
2.16.1. Hash Operatoren
es gilt %lexikon , siehe oben.
2.16.2. Löschen von Einträgen im Hash
mit Hilfe von delete:
my % lexikon = (" ich " ,3 ," du " ,10 ," er " ,5 ," sie " ,10 ," es " ,20);
delete ( $lexikon { ' es '});
ergibt:
% lexikon = (" ich " ,3 ," du " ,10 ," er " ,5 ," sie " ,10);
2.16.3. Zugriff auf den Hash
2.16.3.1. Zugriff auf alle Keys im Hash
keys
– Funktion
Die Funktion keys liefert als Ergebnis alle keys eines Hashes als Liste:
Beispiel 2.50
@key_lexikon = keys % lexikon ;
2.16.3.2. Zugriff auf alle Werte im Hash
values
– Funktion
Die Funktion values liefert als Ergebnis alle values eines Hashes als Liste:
Beispiel 2.51
@values_lexikon = values % lexikon ;
Tabelle 2.13 fasst Zugriff auf Elemente und sort Anweisungen für Hashes zusammen
Numerisches sortiern nach dem Wert
print keys %lexikon;
print values %lexikon;
print @lexikon{’ich’,’du’,’er’};
print scalar(keys %lexikon);
print „Ich bin da! \n“ if exists $lexikon{’er’};
foreach $elem (sort keys %lexikon) {
print "$elem is $lexikon{$wort} \n";
}
foreach $elem
(sort {$lexikon {$a} cmp $lexikon {$b}} keys %lexikon ) {
print "$elem is $lexikon{$elem}\n";
}
foreach $elem (
sort { $lexikon {$b} cmp $lexikon {$a} } keys %lexikon) {
print "$elem is $lexikon{$elem}\n";
}
foreach $elem (
sort { $lexikon {$a} <=> $lexikon {$b} } keys %lexikon) {
print "$elem is $lexikon{$elem}\n";
}
Tabelle 2.13.: Hash: Zugriff und sort Anweisungen
umgekehrt alphabetisch sortieren nach dem Wert
Alphabetisch sortieren nach dem Wert
Alle Keys
Alle Werte
Ein Teil des Hash
Wieviele Elemente?
Existiert der Key?
Sortieren nach dem Key
2.16. Datenstrukturen 2: Hashes
55
56
2. Die Programmiersprache Perl
Interaktives Abfragen eines Hashes:
print " Eingabe Abkuerzung :";
chomp ( $abk = < STDIN >);
print " $abkuerzungen { $abk } = $abk \ n "
if defined $abkuerzungen { $abk };
Beispiel 2.52: Einlesen und Sortieren von Werten eines Hashes
#!/ usr / bin / perl -w
# file :/ DieSprache / hashSort . perl
# Beispiel zum Einlesen von Werten eines Hashes und
# zum Sortieren eines Hashes
use strict ;
use utf8 ;
{
my ( $wort , $elem );
my % wortliste ;
while ( $wort = <> ) {
chomp $wort ;
if ( defined $wortliste { $wort } ) {
$wortliste { $wort }++;
}
else {
$wortliste { $wort } = 1;
}
}
foreach ( keys % wortliste ) {
print " Der key $_ kommt $wortliste { $_} Mal vor \ n ";
}
print "/////////////\ n ";
foreach $elem ( reverse sort numeric keys % wortliste ) {
print " Der key $elem kommt $wortliste { $elem } Mal vor \ n ";
}
# hier folgt eine Subroutine , Siehe Kapitel über Subroutinen
sub numeric { $wortliste { $a } <= > $wortliste { $b } }
}
3. Reguläre Ausdrücke in Perl
Zur Suche von Zeichenfolgen innerhalb von Strings haben wir bisher nur den Vergleichsoperator und den Zugriff auf die einzelnen Buchstaben kennen gelernt. In Perl kann man
aber mit Hilfe von regulären Ausdrücken beliebige Zeichenfolgen innerhalb eines Strings
auffinden. Unter einem regulären Ausdruck verstehen wir eine Folge von Zeichen und
Metazeichen, die eine Klasse von Zeichenfolgen beschreiben. Um einen regulären Ausdruck
von einem String zu unterscheiden, muss der reguläre Ausdruck von slashes eingeschlossen
werden:
" abc "
/ abc /
ist ein String
ist ein regulärer Ausdruck
Um eine Skalare Variable mit einem regulären Ausdruck zu vergleichen gibt es die
Binding Operatoren :
=~
und
!~
3.1. Buchstaben in einem regulären Ausdruck
Jeder Buchstabe in einem regulären Ausdruck stimmt nur mit dem gleichen Buchstaben
im Skalar überein. Groß- und Kleinschreibung wird unterschieden.
Beispiel 3.1
#!/ usr / bin / perl
# Suchen eines Strings mithilfe von RA
use strict ;
{
}
my $str ;
$str = " Hallo ";
if ( $str =~ / Hallo /) {
print (" gefunden \ n ");
}
if ( $str !~ / a /) {
print (" kein a gefunden \ n ");
}
3.2. Übersicht über Metazeichen
Metazeichen sind Symbole, die ein spezielle Bedeutung haben und dazu beitragen, dass
flexiblere reguläre Ausdrücke geschaffen werden können, um Varianten eines Strings zu
finden. In Perl gibt es folgende Metacharachters:
\
|
(
[
{
^
$
*
)
]
}
57
58
3. Reguläre Ausdrücke in Perl
+
?
.
3.3. Metazeichen . = Wildcard
Dieses Metazeichen steht stellvertretend für genau ein Zeichen, aus der Menge aller vorkommenden atomaren Zeichen.
if ( $str =~ / H . llo /) {
print (" gefunden \ n ");
}
Der regluäre Ausdruck findet alle Zeichenfolgen, die mit H beginnen und mit llo enden.
Zwischen H und llo darf ein beliebiger Buchstabe bzw. atomares Zeichen stehen.
3.4. Metazeichen [ ] = Buchstabenbereiche
Buchstabenbereiche werden von den Metazeichen „Eckige Klammern“ umschlossen und
spezifizieren alle Buchstaben, die an dieser Stelle zugelassen sind.
z . B . / Hall [ iao ]/
# Findet die Strings : Hallo , Halli , Halla
z . B . / Hallo [a - z ]/ # Findet alle Strings die mit Hallo beginnen
# und am Ende einen Kleinbuchstaben haben .
z . B . /[ Hh ] allo /
# Findet
die Strings : Hallo und
hallo
3.5. Metazeichen * , + , ? { } = Quantifizierung
Diese Metazeichen legen fest, wie oft der vorherige Buchstabe wiederholt wird:
*
+
?
{n , m }
{n}
Beliebig oft
Mindestenes einmal
Null oder einmal
Mindestens n mal , aber maximal m mal
Genau n mal
Beispiel 3.2: Reguläre Ausdrücke: Quantifizierung
/ Hallo */
# Findet den String " Hall " und alle Strings " Hallo "
# mit beliebig vielen " o " am Ende
/ Hallo +/
# Findet alle Strings " Hallo " mit beliebig vielen " o " am Ende
/ Hallo ?/
# Findet den String " Hall " und " Hallo "
/ Hall [ oi ]{1 ,3}/
# Findet den String " Hallo " , " Halli " , " Hallio " ,
#" Hallooo " , " Hallooi " usw .
3.6. Metazeichen ( ) = Zeichengruppierung
59
3.6. Metazeichen ( ) = Zeichengruppierung
Sollen Zeichen zusammengefasst und als eine Einheit gesehen werden, müssen sie mit
runden Klammern eingeschlossen werden.
Beispiel 3.3: Reguläre Ausdrücke: Zeichengruppierung
/ geh ( en )?/
# Findet geh und gehen
/ geh ( en )*/
# Findet geh , gehen , gehenen , usw .
3.7. Metazeichen ˆ = Anfang der Zeile
Soll ein String am Anfang der Zeile gesucht werden, dann muss am Anfang des regulären
Ausdrucks ein ˆ stehen.
Beispiel 3.4: Reguläre Ausdrücke: Anfang der Zeile
/^ Toni /
# Findet den Namen Toni am Anfang einer Zeile
3.8. Metazeichen $ = Ende der Zeile
Soll ein String eine Zeile abschließen, dann muss am Ende des regulären Ausdrucks ein $
stehen.
Beispiel 3.5: Reguläre Ausdrücke: Ende der Zeile
/ Tummi$ /
# Findet den Namen Tummi am Ende einer Zeile .
3.9. Metazeichen \= Ausschalten der Metazeichenerkennung
Soll in einem String eine Zeichenkette gefunden werden, die einen Metacharacter enthält,
dann muss im regulären Ausdruck der gesuchte Metacharacter mit einem Backslash vor
der Interpretierung als Metacharacter geschützt werden.
Beispiel 3.6: Reguläre Ausdrücke: Ausschalten der Metazeichenerkennung
/ Toni \+ Sepp /
# Findet den Namen Toni + Sepp
Beispiel 3.7: Zeilenweises lesen aus der Datei „zeilen.txt“ und mit einem regulären Ausdruck
vergleichen
#!/ usr / bin / perl
# file :/ RegulaereAusdruecke / reg . perl
# Suchen einer Zeichenkette beim Einlesen einer Textdatei
use strict ;
{
my $filename = " zeilen . txt ";
my $line ;
open ( EINGABE , $filename );
while ( $line = < EINGABE > ) {
chomp ( $line );
if ( $line =~ /^ Hallo / && $line !~ / Hansi$ / ) {
print (" Hallo am Anfang einer Zeile gefunden , die ");
print (" nicht mit Hansi endet .\ n ");
print (" $line \ n ");
60
3. Reguläre Ausdrücke in Perl
}
}
}
3.10. Metazeichen [ˆ ] = negierte Buchstabenbereiche
Negierte Buchstabenbereiche werden von den Metazeichen „Eckige Klammern“ und dem ˆ
-Buchstaben als erster Buchstabe nach der öffnenden Klammer definiert. Sie spezifizieren
alle Buchstaben, die an dieser Stelle nicht zugelassen sind.
Beispiel 3.8: Reguläre Ausdrücke: negierte Buchstabenbereiche
/ Hall [^ ioa ]/ # Findet die Strings die mit Hall beginnen ,
# außer Hallo , Halli , Halla
/ Hallo [^ a - zäüöß ] $ / # Findet alle Strings am Ende der Zeile ( Strings ) die mit
# Hallo beginnen und mit keinem Kleinbuchstaben enden .
3.11. Buchstabenklassen ohne UNICODE
Ein Ausdruck der Form [[:name:]] findet alle Buchstaben, die zu dieser Buchstabenklasse
gehören, z.B.
Beispiel 3.9
[[: lower :]]
findet alle Kleinbuchstaben
Die Buchstabenklassen können in Perl auch mit einer Escape-Sequenz ausgedrückt werden.
Die wichtigsten Buchstabenklassen sind:
Buchstabenklasse
[[:digit:]]
[[:lower:]]
[[:upper:]]
[[:word:]]
[[:space:]]
[ˆ[:digit:]]
[ˆ[:lower:]]
[ˆ[:upper:]]
[ˆ[:word:]]
Escape Sequenz
\d
\l
\u
\w
\s
\D
\L
\U
\W
\b
Beschreibung
Dezimalzahl
Kleinbuchstabe
Großbuchstabe
Wort-Buchstabe
Leerzeichen/ Tabs
keine Dezimalzahl
kein Kleinbuchstabe
kein Großbuchstabe
kein Wort-Buchstabe
Wortgrenze
Tabelle 3.1.: Buchstabenklassen ohne UNICODE
3.12. Buchstabenklassen mit UNICODE
Wenn das Perl Programm im UNICODE Mode läuft:
• Verwendung des Pragmas: use locale;
• Starten des Perl Programms mit der Option -C (für UTF-8 Files)
• die Standardkodierung der Console (UTF-8)
3.13. Zugriff auf gruppierte Teile des Regulären Ausdrucks
61
dann gilt die Buchstabenklasse \w (Wort-Buchstabe) nicht mehr.
Um Buchstabenklassen weiterhin zu verwenden, müssen die Definitionen von UNICODE
verwendet werden, siehe Tabelle 3.2. UNICODE führt sogenannte Properties ein, die
mit einem \p und den in geschweiften Klammern einschlossenen Eigenschaften notiert
werden. Verwendet man als UNICODE Property nicht den Kleinbuchstaben p sondern den
Großbuchstaben P, dann spricht UNICODE die Negation der in geschweiften Klammern
einschlossenen Eigenschaften an. Es gibt noch eine weitere Möglichkeit eine Eigenschaft zu
negieren: Der in geschweifter Klammer definierten Eigenschaft wird das Negationszeichen ^
vorgestellt.
Beispiel 3.10
\p{L}
\P{L}
\ p { Ll }
\ P { Ll }
\ p {^ Ll }
Letter - Buchstabe
KEIN Letter - Buchstabe
lowercase Buchstabe findet alle Kleinbuchstaben
alle Buchstaben , außer die Kleinbuchstaben
Negation : kein lowercase Buchstabe : findet alle Zeichen ,
außer Kleinbuchstaben
Die Buchstabenklassen können in Perl auch mit einer UNICODE Property Sequenz ausgedrückt werden. Die wichtigsten Buchstabenklassen und ihre UNICODE Property Sequenzen
sind:
UNICODE Property Sequenz
\p{N}
\p{L}
\p{Ll}
\p{Lu}
\p{Z}
\P{Lu}
\p{ˆLu}
Beschreibung
Dezimalzahl
Buchstabe
Kleinbuchstabe
Großbuchstabe
Trennzeichen
Kein Großbuchstabe
Kein Großbuchstabe
Tabelle 3.2.: Buchstabenklassen mit UNICODE
3.13. Zugriff auf gruppierte Teile des Regulären Ausdrucks
Man kann reguläre Ausdrücke mit runden Klammern strukturieren. Dadurch erreicht man
erstens eine Gruppierung von Ausdrücken und zweitens einen Zugriff auf Teile des gesamten
Treffers (Substrings). Perl nummeriert die Gruppen durch und erlaubt auf diese über die
Variablen $1,$2 zuzugreifen.
Beispiel 3.11: Zugriff auf gruppierte Teile des Regulären Ausdrucks
#!/ usr / bin / perl
# file :/ RegulaereAusdruecke / wortGruppe . perl
# Extrahiert 3 Wörter aus einem Trigram
# Aufruf mit perl -C wortGruppe . perl
use strict ;
use locale ; # schaltet auf UNICODE Mode , verhindert , dass
# \ w auch Umlaute findet
{
my $line ;
while ( $line = <> ) {
chomp ( $line );
62
3. Reguläre Ausdrücke in Perl
}
}
}
if ( $line =~ /^(\ w +)\ s +(\ w +)\ s +(\ w +) $ / ) {
print (" Backslash w Search : Trigram gefunden : $1 .. $2 .. $3 \ n ");
if ( $line =~ /^(\ p { L }+)\ s +(\ p { L }+)\ s +(\ p { L }+) $ / ) {
print (" UNICODE p { L } Search : Trigram gefunden : $1 .. $2 .. $3 \ n ");
}
Findet alle Zeilen mit 3 Wörtern und gibt bei der Zeile:
Das ist gut
folgendes aus:
Das .. ist .. gut
3.14. Globales Suchen in einer Zeile
Standardmäßig sucht Perl, genauso wie der UNIX-Befehl grep, nur nach dem ersten
Vorkommen einer Zeichenkette innerhalb eines String. Kommt eine Zeichenkette mehrmals in
einem String vor, dann übersieht Perl die nachfolgenden Zeichenketten, da die Suchposition
immer am Anfang der Zeile bleibt.
Dieses Verhalten kann dadurch geändert werden, dass die Suche nach dem regulären
Ausdruck auf „global-Search“ gesetzt wird. Dazu muss dem regulären Ausdruck ein /g
nachgestellt werden. Findet Perl in einer Zeile die gesuchte Zeichenkette, dann setzt Perl
in der Zeile hinter der gefundenen Zeichenkette die Suche fort.
Beispiel 3.12
#!/ usr / bin / perl
# Beispiel für Globales Suchen
use strict ;
{
my ( $line );
print " Eingabe > > >";
chomp ( $line = < >);
while ( $line =~ /\ s *(\ w +)\ s */ g ) {
print (" found : $1 \ n ");
}
}
> perl global . perl
Eingabe : ich du er sie
found : ich
found : du
found : er
found : sie
3.15. Ersetzen von Strings: substitute
63
3.15. Ersetzen von Strings: substitute
In Perl können Zeichenketten von anderen Zeichenketten ersetzt werden. Dazu gibt es
den substitute Befehl. Mit Hilfe eines Regulären Ausdrucks kann spezifiziert werden, was
ersetzt werden soll.
• Ersetzt in der Zeile $line das erste Auftreten der Zeichenkette „von“ durch „nach“
$line =~ s / von / nach /;
• Ersetzt caseinsensitiv in der Zeile $line das erste Auftreten der Zeichenkette „von“
durch „nach“. Es werden alle Groß-/Kleinschreibungskombinationen von „von“ akzeptiert.
$line =~ s / von / nach / i ;
• Ersetzt in der Zeile $line jedes Auftretens der Zeichenkette „von“ durch „nach“
$line =~ s / von / nach / g ;
• Ersetzt in der Zeile $line alle vierstelligen Zahlen durch den String „nnnn“
$line =~ s /\ d \ d \ d \ d / nnnn / g ;
• oder
$line =~ s /\ d {4}/ nnnn / g ;
3.16. Greedy-Nongreedy Verhalten bei Quantifizierung
Bei den * und + Quantifizierungen von Zeichen stellt sich die Frage, wie viele Zeichen
Perl in einem Pattern matched. Per Default versucht Perl so viele Zeichen zu matchen wie
möglich. Dieses Verhalten nennt man „Greedy-Matching“:
Beispiel 3.13: Greedy Verhalten bei Quantifizierung
$wort = " Schifffahrt ";
$wort =~ s / f +/ x /;
print " greedy matching : $wort \ n ";
Perl matched alle drei f in Schifffahrt und ersetzt sie durch ein x:
greedy matching : Schixahrt
Das Greedy-Matching wird unterbunden, wenn dem Quantifizierer ein Fragezeichen nachgestellt wird:
Beispiel 3.14: Nongreedy Verhalten bei Quantifizierung
$wort = " Schifffahrt ";
$wort =~ s / f +?/ y /;
print " NON greedy matching : $wort \ n ";
Perl ist auf NON Greedy gesetzt und matched nur das erste f in Schifffahrt und ersetzt es
durch ein y:
NON greedy matching : Schiyffahrt
Beispiel 3.15: Nongreedy Verhalten mit Global Option bei Quantifizierung
$wort = " Schifffahrt ";
$wort =~ s / f +?/ y / g ;
print " NON greedy GLOBAL matching : $wort \ n ";
64
3. Reguläre Ausdrücke in Perl
Perl ist zwar auf NON Greedy gesetzt, aber die Option global matched jedes einzelne f in
Schifffahrt und ersetzt jedes einzelne durch ein y
NON greedy GLOBAL matching : Schiyyyahrt
3.17. Zugriff auf gruppierte Teile des regulären Ausdrucks beim Ersetzen
von Zeichenketten
Wie vorher erwähnt, kann man reguläre Ausdrücke mit runden Klammern strukturieren.
Dadurch kann man beim Ersetzen von Zeichenketten auf die gefundenen Gruppen zugreifen.
Perl nummeriert die Gruppen durch und erlaubt auf diese über die Variablen \1, \2
zuzugreifen.
Beispiel 3.16: Zugriff auf gruppierte Teile des regulären Ausdrucks beim Ersetzen von
Zeichenketten
$zeile =" Ja Nicht ";
$zeile =~ s /^(\ w +) (\ w +) $ / $2 $1 /;
print (" $zeile \ n ");
Dreht in allen Zeilen mit 2 Wörtern die Reihenfolge der Wörter um.
Ja Nicht
ergibt folgendes:
Nicht Ja
3.18. Suchen über Zeilengrenzen hinweg
Manche zu suchenenden Ausdrücke lassen sich schlecht innerhalb einer Zeile finden. Hier
kann es sinnvoll sein, über Zeilengrenzen hinweg zu suchen.
Der Input Record Separator $/ entscheidet, an welchem Zeichen der Input endet. Voreingestellt ist der Input Record Separator auf das Newline-Zeichen. Daher kann man den Input
zeilenweise lesen, wenn man while ($input = <>) {... schreibt.
Um den Input Record Separator auf ein anderes Zeichen zu setzen kann man diesen einfach
zuweisen, zum Beispiel auf ein Space.
$/ = " ";
Um über Zeilengrenzen hinweg zu suchen macht es Sinn den Input Record Separator
komplett auszuschalten.
undef $/;
Innerhalb des regulären Ausdrucks, der über die Zeilengrenzen hinweg gesucht werden soll,
gibt es weitere Punkte zu beachten:
• Um den Dot Operator . über Zeilengrenzen hinweg verwenden zu können, muss die
Option /s eingeschaltet werden.
• Um ^ und $, also Zeilenanfang und -Ende, weiterhin nutzen zu können, muss die
Option /m eingeschaltet werden.
3.18. Suchen über Zeilengrenzen hinweg
Beispiel 3.17: Suchen über Zeilengrenzen hinweg
#!/ usr / bin / perl
# Suchen über Zeilengrenzen hinweg
use strict ;
use utf8 ;
use locale ;
{
my $input ;
open ( TEXT ," <: utf8 " ," sz_artikel . txt ") or die " file not found !";
undef $ /; # Input Record Separator wird ausgeschaltet
$input = < TEXT >;
# $input enthält den kompletten Text
# findet zwei großgeschriebene Wörter nacheinander
while ( $input =~ / (\ p { Lu }\ p { Ll }+\ s \ p { Lu }\ p { Ll }+)/ g ) {
print $1 ,"\ n ";
}
# findet Wortfolgen die mit Punktuationszeichen enden
while ( $input =~ /(\ p { Lu }.+?\ p { P })/ gs ) {
print $1 ,"\ n ";
}
# findet Zeilen die mit Punktuationszeichen enden
while ( $input =~ /^(\ p { Lu }.+?\ p { P }) $ / gm ) {
print $1 ,"\ n ";
}
}
close TEXT ;
65
4. Systemroutinen in Perl
4.1. Vorbemerkung
Perl stellt eine Vielzahl von fertigen Routinen zur Verfügung. Die folgende Auswahl stellt
daher nur einen sehr geringen Teil der in Version Perl 6 vorhandenen Routinen vor. Prinzipiell werden Systemroutinen mit ihrem Namen, dem system subroutine identifier, aufgerufen.
Nach dem Namen werden geklammert Argumente an die Systemroutine übergeben. Systemroutinen geben nach ihrer Ausführung einen Wert an den aufrufenden Programmteil
zurück, der mit einer Zuweisung auf eine Variable geschrieben werden kann.
Formatierungskonvention:
• Die Argumente von Systemroutinen können entweder in Klammern eingeschlossen
werden oder als eine mit Komma getrennte Folge von Einzelargumenten übergeben
werden:
• Stehen die Argumente in Klammern, dann steht zwischen dem Routinennamen in
der öffnenden Klammer kein Space
• Werden die Argumente als Reihung aufgelistet, dann steht zwischen dem Routinennamen und den Agumenten ein Leerzeichen.
Beispiel 4.1
print (" Wort ");
print " Wort ";
4.2. split
Aufruf : < list variable > = split (/ < pattern >/ , < string > | < skalar variable >);
Die Routine split teilt eine Zeichenkette in Einheiten, die auf eine list variable geschrieben
werden können. Die Zeichenkette wird der Routine entweder direkt als String oder als skalare
Variable übergeben. Die Aufteilung des Strings erfolgt nach dem in pattern angegebenen
Trennzeichen (auch mehrere Zeichen sind möglich). Wird kein Trennzeichen angegeben, so
wird nach whitespace(Leerzeichen, Tab, Newline) getrennt. Soll nach einzelnen Buchstaben
getrennt werden, so gibt man als pattern den leeren String, dargestellt durch // an. Die
angegebenen Trennzeichen werden nicht mit zurückgegeben, bei der Zuweisung auf ein
Array gehen die Trennzeichen also verloren.
Beispiel 4.2: Einen Satz in Wörter zerlegen
$satz
= " Das ist ein Satz ";
@woerter = split (/ / , $satz );
Ergebnis :
$woerter [0] == Das
$woerter [1] == ist
66
4.3. ord
67
$woerter [2] == ein
$woerter [3] == Satz
Beispiel 4.3: Ein Wort in Buchstaben zerlegen
$wort = " Wort ";
@buchstaben = split (// , $wort );
Ergebnis :
$buchstaben
$buchstaben
$buchstaben
$buchstaben
[0]
[1]
[2]
[3]
==
==
==
==
W
o
r
t
Beispiel 4.4: Einen Text in Wörter zerlegen
Einen Text in Wörter zerlegen. Das heißt, nicht nur an Leerzeichen trennen, sondern auch
an .,;:
#!/ usr / bin / perl
# Zerlegen eines Texts in Wörter
use strict ;
{
my ( $text , $zeile );
my ( @woerter );
my % anzahl ;
$text = " info . txt ";
open ( INFO , $text );
}
while ( $zeile = < INFO >) {
chomp $zeile ;
@woerter = split (/[ ,. ;:]+/ , $zeile ); # ohne '+ ' ist das haeufigste Wort " "
foreach my $wort ( @woerter ) {
$anzahl { $wort }++;
}
}
close INFO ;
4.3. ord
Aufruf : < skalar variable > = ord ( < char >| < skalar variable >)
Die Routine ord gibt den dezimalen ASCII Wert des ersten übergebenen Zeichens zurück.
Dieser Wert kann über eine Zuweisung auf eine skalare Variable geschrieben werden. Das
Argument von ord darf sowohl ein String sein, als auch eine skalare Variable, die einen
String enthält.
Beispiel 4.5: Ermitteln des ASCII Wertes von einem Buchstaben
$buchstabe
= " u ";
$ascii_von_u = ord ( $buchstabe );
Ergebnis :
$ascii_von_u == 117
68
4. Systemroutinen in Perl
4.4. chr
Aufruf : < skalar variable > = chr ( < number >| < skalar variable >)
Die Routine chr gibt das ASCII Zeichen zurück, das unter dem übergebenen Wert kodiert
ist. Dieser Wert kann über eine Zuweisung auf eine skalare Variable geschrieben werden.
Das Argument von char darf sowohl eine Dezimalzahl sein, als auch eine skalare Variable,
deren r-value eine Zahl ist.
Beispiel 4.6: Ermitteln des unter 117 kodierten Zeichens
$ascii_zahl
= 117;
$ascii_zeichen_117 = chr ( $ascii_zahl );
Ergebnis :
$ascii_zeichen_117 == u
4.5. length
Aufruf : < skalar variable > = length ( < string >| < skalar variable >)
Die Routine length gibt die Anzahl der Zeichen zurück, die das Argument enthält. Dieser
Wert kann über eine Zuweisung auf eine skalare Variable geschrieben werden. Argument
von length darf sowohl ein string sein, als auch eine skalare Variable, deren r-value ein
string ist.
Beispiel 4.7: Ermitteln der Länge eines Strings
$wort
= " Wort ";
$laenge = length ( $wort );
print (" Das Wort hat $laenge Buchstaben ");
Ausgedruckt wird :
Das Wort hat 4 Buchstaben
4.6. scalar
Aufruf : < skalar variable > = scalar ( < list variable >)
zwingt ein Array in einen skalaren Kontext. Die einzige Information, die dann übrig
bleibt, ist die Anzahl der Elemente. Diesen Wert liefert die Funktion an die aufrufende
Stelle zurück. Es ist also möglich die Information sofort einer skalaren Variablen mit dem
Zuweisungsoperator „=“ zuzuweisen.
Auf keinen Fall kann die Länge eines Arrays mit der Funktion length bestimmt werden. Diese
dient dazu die Länge eines Skalars zu bestimmen. Lediglich bei der Buchstabenzerlegung
eines Strings hatten wir die Arraylänge des Buchstabenarrays indirekt mithilfe von scalar
bestimmt. Warum: Das Buchstabenarray muss ja gerade soviel Elemente haben wie der
String Buchstaben.
Beispiel 4.8: Ermitteln der Anzahl der Elemente in einer Liste
@worte = (" Heute " ," regnet " ," es ");
$laenge = scalar ( @worte );
print (" Die Liste Worte hat $laenge Listenelemente ");
4.7. join
69
Ausgedruckt wird :
Die Liste Worte hat 3 Listenelemente
4.7. join
Aufruf : < skalar variable > = join ( < string > , < list variable >)
Die Routine join fügt alle Elemente aus der list variable zu einer Zeichenkette zusammen.
Die einzelnen Elemente der list variable werden dabei durch die im ersten Argument von
join angegebene Zeichenkette getrennt. Wird der leere String als Trenner angegeben, so
werden alle Elemente der list variable zusammengeschrieben. Der von join zurückgegebene
String kann über eine Zuweisung auf eine skalare Variable geschrieben werden.
Beispiel 4.9: Ein als array gespeichertes Wort in einen string schreiben
@wort_in_buchstaben ;
$wort_in_buchstaben [0]
$wort_in_buchstaben [1]
$wort_in_buchstaben [2]
$wort_in_buchstaben [3]
=
=
=
=
" W ";
" o ";
" r ";
" t ";
$wort_als_string = join ("" , @wort_in_buchstaben );
$buchstaben_als_string = join (" " , @wort_in_buchstaben );
print (" $wort_als_string
$buchstaben_als_string ");
Ausgedruckt wird :
Wort
W o r t
4.8. pop
Aufruf : < variable > = pop ( < array variable >)
Die Routine pop entfernt das letzte Element aus der array variable und liefert es als Ergebnis
zurück. Über eine Zuweisung kann das entfernte Element auf eine Variable geschrieben
werden. Das Array wird um 1 gekürzt.
Beispiel 4.10: Das letzte Element in einem Array entfernen
@liste ;
$liste [0]
$liste [1]
$liste [2]
$liste [3]
=
=
=
=
" eins ";
" zwei ";
" drei ";
" vier ";
$letztes = pop ( @liste );
print (" Das letzte Element in der Liste war $letztes ");
Ausgedruckt wird :
Das letzte Element in der Liste war vier
70
4. Systemroutinen in Perl
4.9. push
Aufruf : push ( < array variable > , < skalar variable >)
Die Routine push hängt das in skalar variable angegebene Element an die array variable an.
Die array variable wird also als Stapel betrachtet. Das letzte Element ist immer zuoberst.
Das array wird um 1 verlängert.
Beispiel 4.11: Ein neues Element ans Ende eines Arrays stellen
@liste ;
$liste [0]
$liste [1]
$liste [2]
$liste [3]
=
=
=
=
" eins ";
" zwei ";
" drei ";
" vier ";
$neues
= " fünf ";
push ( @liste , $neues );
print (" Das letzte Element in der Liste ist jetzt $liste [4]");
Ausgedruckt wird :
Das letzte Element in der Liste ist jetzt fünf ;
4.10. shift
Aufruf : < variable > = shift ( < array variable >)
Die Routine shift entfernt das erste Element aus der array variable und liefert es als
Ergebnis zurück. Alle Elemente in array variable rücken im Index um 1 nach vorne. Über
eine Zuweisung kann das entfernte Element auf eine Variable geschrieben werden.
Beispiel 4.12: Das erste Element in einem Array entfernen
@liste ;
$liste [0]
$liste [1]
$liste [2]
$liste [3]
=
=
=
=
" eins ";
" zwei ";
" drei ";
" vier ";
$erstes = shift ( @liste );
print (" Das erste Element in der Liste war $erstes \ n ");
print (" Das neue erste Element in der Liste ist $liste [0]");
Ausgedruckt wird :
Das erste Element in der Liste war eins
Das neue erste Element in der Liste ist zwei
4.11. unshift
71
4.11. unshift
Aufruf : unshift ( < array variable > , < variable >)
Die Routine unshift fügt vor das erste Element aus <array variable> das Element <variable>
ein. Alle Elemente in <array variable> rücken im Index um 1 nach hinten.
Beispiel 4.13: Ein neues Element an den Anfang eines Arrays stellen
@liste ;
$erstes =" null ";
$liste [0] = " eins ";
$liste [1] = " zwei ";
$liste [2] = " drei ";
$liste [3] = " vier ";
unshift ( @liste , $erstes );
print (" Das erste Element in der Liste soll sein : $erstes \ n ");
print (" Das neue erste Element in der Liste ist $liste [0]");
Ausgedruckt wird :
Das erste Element in der Liste soll sein : null
Das neue erste Element in der Liste ist null
4.12. reverse
Aufruf : < variable > = reverse ( < variable >)
Die Routine reverse liefert im Array Kontext alle Elemente in umgekehrter Reihenfolge. In
einem skalaren Kontext liefert reverse die Zeichen des Skalars in umgekehrter Reihenfolge.
Über eine Zuweisung können Arrayelemente bzw. Zeichen auf ein Array bzw. einen Skalar
geschrieben werden.
Beispiel 4.14: Die Elemente in einem Array umdrehen
@liste ;
@liste_umgedreht ;
$liste [0] = " eins ";
$liste [1] = " zwei ";
$liste [2] = " drei ";
$liste [3] = " vier ";
@liste_umgedreht = reverse ( @liste );
print (" @liste \ n ");
print (" @liste_umgedreht ");
Ausgedruckt wird :
eins zwei drei vier
vier drei zwei eins
72
4. Systemroutinen in Perl
Beispiel 4.15: Palindrom
Ist ein Wort ein Palindrom?
my $wort = " reliefpfeiler ";
if ( $wort eq reverse ( $wort )){
print (" $wort ist ein Palindrom ");
} else {
print (" $wort ist kein Palindrom ");
}
Ausgedruckt wird :
reliefpfeiler ist ein Palindrom
4.13. sort
Aufruf : < list variable > = sort ( < list variable >)
Die Routine sort gibt die Elemente der list variable in aufsteigender Reihenfolge, entsprechend den normalen Konventionen des Zeichenvergleichs, zurück. Über eine Zuweisung
können die Elemente auf ein Array geschrieben werden.
Beispiel 4.16: Die Elemente in einem Array sortieren
my @woerter ;
my @woerterbuch ;
$woerter [0] = haus ;
$woerter [1] = aal ;
$woerter [2] = computer ;
$woerter [3] = compiler ;
@woerterbuch = sort ( @woerter );
print (" @woerterbuch ");
Ausgedruckt wird :
aal compiler computer haus
Implementierung von sort
Alphabetisch sortiert:
foreach my $wort ( sort keys % worthash ) {
print " $wort \ n ";
}
Nach Häufigkeit sortiert:
foreach my $wort ( sort { $worthash { $b } <= > $worthash { $a } } keys % worthash ) {
print " $wort = $worthash { $wort }\ n ";
}
5. Subroutinen in Perl
Vorbemerkung
Um große Programmieraufgaben übersichtlich und strukturiert zu realisieren, ist es sehr
empfehlenswert, Teilaufgaben des Programms in eigenen Programmteilen, sogenannten
Unterprogrammen, realisieren zu lassen.
Unterprogramme können selbstständig entwickelt, getestet, optimiert, von Fehlern befreit
und in anderen Programmen wiederverwendet werden. Die Unterprogrammtechnik ist auch
das zentrale Konzept bei der modularen Programmierung: Größere Unteraufgaben werden
in eigenen Modulen erledigt.
Eine Programmiersprache, die die Unterprogrammtechnik unterstützt muss in der Lage
sein, Programmteile zusammenzufassen, diesen Programmteilen einen Namen zu geben
und ihnen Werte zu übergeben, bzw. innerhalb dieser Programmteile Werte ermitteln zu
lassen, die im aufrufenden Programm zur Verfügung stehen.
Perl unterstützt die Unterprogrammtechnik, Programmteile können in Unterprogrammen,
genannt Subroutinen, zusammengefasst werden. Subroutinen können Werte übergeben
werden, die Werte können in Subroutinen weiterverarbeitet werden und sie können dem
aufrufenden Programm zurückgegeben werden. Das Unterprogramm kann somit eine eigene
Aufgabe realisieren und mit dem aufrufenden Programm zusammenarbeiten.
Ein Beispiel für Subroutinen in Perl ist z.B. die Funktion print zum Ausgeben von Text.
print (" Hallo ");
Der Subroutine print wird das Argument "Hallo" übergeben: Im Unterprogramm print
wiederum werden alle notwendigen Systemroutinen aufgerufen, die auf dem Bildschirm
genau an der richtigen Stelle den Text "Hallo" ausgeben.
5.1. Definition von Subroutinen in Perl
In Perl besteht eine Subroutine aus einem
• Subroutinenkopf und einem
• Subroutinenrumpf.
Im Subroutinenkopf wird der Name der Subroutine festgelegt. In Perl steht es dem Benutzer
frei, hinter dem Subroutinennamen in runden Klammer eingeschlossen die Parametertypen der Subroutine aufzulisten. Einen Subroutinenkopf mit Deklaration der Typen der
Parameter nennt man in Perl Subroutinen-Prototypen. Die Parameter, mit denen eine
Subroutine aufgerufen wird, stellen die Schnittstelle zwischen aufrufendem Programm und
Unterprogramm dar.
Der Subroutinenrumpf beginnt hinter dem Subroutinenkopf und wird mit geschweiften
Klammern umschlossen.
Er besteht aus
• Parametersektion und
• Anweisungsblock.
73
74
5. Subroutinen in Perl
In der Parametersektion werden die Variablen deklariert, die innerhalb der Subroutine
verwendet werden. Ausserdem werden hier die Parameterwerte, mit denen eventuell die
Subroutine aufgerufen wird, den Subroutinenvariablen zur Weiterverarbeitung übergeben.
Im Anweisungsblock stehen alle Anweisungen, die ausgeführt werden, wenn die Subroutine
abgearbeitet wird.
Eine Subroutine wird mit ihrem Namen und eventuellen Argumenten aufgerufen.
Da die Programmiersprache Perl nicht überprüft, ob die Anzahl und der Typ der Argumente,
mit denen eine Subroutine definiert ist und aufgerufen wird, übereinstimmt, muss der
Programmierer unbedingt selbst darauf achten, dass es hier keine Widersprüche gibt.
5.2. Datenaustausch zwischen Subroutinen und Hautpprogramm
Subroutinen können mit oder ohne Argumenten aufgerufen werden, der Praefix & vor dem
Subroutinennamen kann weggelassen werden.
ACHTUNG: Perl überprüft nicht, ob die Anzahl und Art der Argumente, mit denen eine
Subroutine aufgerufen wird, mit der Definition der Subroutine übereinstimmt.
Den Datenaustausch zwischen dem aufrufenden Programm und einer Subroutine kann
über drei Arten realisiert werden:
• Datenaustausch über Argumente:
Die Subroutine wird mit beliebigen Argumenten, sogenannten Argumentvariablen
aufgerufen. Die Werte der Argumentvariablen können sowohl gelesen, als auch verändert werden. Der Programmierer entscheidet, ob eine Subroutine den Wert der
Argumentvariablen, den sie im Hauptogramm besitzt, innerhalb der Subroutine
ändert, oder ob die Subroutine den Wert der Argumentvariablen nur liest.
my $wert =1;
# Aufruf einer Subroutine ohne Argument :
& clear_screen ();
# Aufruf einer Subroutine mit Argument :
& drucke ( $wert );
• Datenaustausch über einen Rückgabewert der Subroutine:
Subroutinen können über ihren Aufruf dem aufrufenden Programm auch Werte
zurückgeben (siehe Rückgabewerte von Subroutinen 5.5)
my $erg ;
# Aufruf der Subroutine mit Rückgabewert :
$erg = & aufeins ();
# innerhalb der Subroutine :
sub aufeins () {
...
return 1;
}
• Datenaustausch über globale Variablen:
Die Subroutine greift auf Variablen zu die nicht innerhalb der Subroutine definiert
werden. Diese Art von Variablen heißt globale Variable (siehe 5.6).
5.3. Zugriff auf die Argumentvariablen in Subroutinen
75
5.3. Zugriff auf die Argumentvariablen in Subroutinen
Werden an eine Subroutine Argumentvariablen übergeben, dann werden direkte Verweise
auf die einzelnen Elemente der Argumentvariablen in der speziellen System-Listenvariable
@_ (genannt STACK Listenvariable) gespeichert. Die STACK Listenvariable steht mit ihren
Werten dem Programmier innerhalb der Subroutine zur Verfügung. Er kann Werte aus
dieser Liste lesen und verändern.
Das erste Argument ist im 0. Element der Liste @_ gespeichert usw.
Beispiel 5.1: Übergabe der Argumente, Speicherung in der STACK Listenvariable @_
my $wert1 =1;
my $wert2 =2;
my @gerade = (2 ,4 ,6)
# Aufruf :
& teste ( $wert1 );
# in @_[0] steht der direkte Verweis auf die Variable $wert1
# Aufruf :
& testezwei ( $wert1 , $wert2 );
# in @_[0] steht der direkte Verweis auf die Variable $wert1
# in @_[1] steht der direkte Verweis auf die Variable $wert2
# Aufruf :
& teste_gerade ( @gerade );
# in @_[0] steht der direkte Verweis auf $gerade [0]
# in @_[1] steht der direkte Verweis auf $gerade [1]
# in @_[2] steht der direkte Verweis auf $gerade [2]
Im folgenden Beispiel wird gezeigt, wie Argumente an eine Subroutine übergeben werden
und wie eine Subroutine auf die Argumentvariable zugreifen kann.
Beispiel 5.2: Übergabe der Argumente, Speicherung und Zugriff auf die STACK Listenvariable
@_
#!/ usr / bin / perl
# file : Subroutinen / uebergabe_stack . perl
# zeigt die Übergabe an Lokale Variablen
{
use strict ' vars ';
my $wert1 =1;
my $wert2 =2;
}
& drucke ( $wert1 );
& druckezwei ( $wert1 , $wert2 );
sub drucke ( $ ) {
print " Argument eins = @_[0]\ n ";
}
sub druckezwei ( $$ ) {
print " Argument eins = @_[0]\ n ";
print " Argument zwei = @_[1]\ n ";
}
76
5. Subroutinen in Perl
Der direkte Zugriff auf Argumentvariablen über die Elemente der speziellen STACK Listenvariablen @_ hat in Perl einen gefährlichen Nebeneffekt: Perl kann über die Arrayelemente
von @_ direkt auf die Argumentvariablen im aufrufenden Programm zugreifen. Jede Veränderung eines Listenelements der speziellen STACK Listenvariable @_ ändert den Wert des
aufrufenden Arguments:
Beispiel 5.3: Übergabe der Argumente an die STACK Listenvariable @_ und Ändern des Wertes
#!/ usr / bin / perl
# file : Subroutinen / uebergabe_stack_incr . perl
# zeigt die Übergabe an Lokale Variablen
{
use strict ' vars ';
my $wert1 =1;
}
& drucke ( $wert1 );
& pluseins ( $wert1 );
& drucke ( $wert1 );
sub drucke ( $ ) {
print " Argument eins = @_[0]\ n ";
}
sub pluseins ( $ ) {
@_[0] = @_[0]+1;
}
Die Technik in einer Subroutine direkt mit den Elementen der speziellen STACK Listenvariable @_ zu arbeiten ist nicht empfehlenswert. Besser ist es bei lesendem Zugriff den
Wert der Argumentvariablen in einer lokalen Variablen der Subroutine zu speichern (siehe:
Lokale Variablen 5.3.1). Wenn der Wert einer Argumentvariablen geändert werden soll,
dann ist es besser der Subroutine eine Referenz auf die Argumentvariable zu übergeben.
Der Programmierer ändert dann über den Umweg der Referenz die Argumentvariable.
(siehe: Die Verwendung von Referenzen 5.4.1)
5.3.1. Lokale Variablen
Lokale Variablen werden häufig auch als lexikalische Variablen bezeichnet. Sie entsprechen
den Ideen modularer Programmierung, d.h. dass man in jedem abgeschlossenen Teil des
Programms sicher sein kann, dass kein Wert unerwünschterweise von außerhalb dieses Teils
geändert werden kann. Dies erleichtert die Fehlersuche und ist im Übrigen unerlässlich,
falls mehrere Teile eines größeren Programms von verschiedenen Personen geschrieben
werden sollen.
Die Deklaration von lokalen Variablen geschieht mit my. Dabei können auch mehrere
Variablen auf einmal deklariert werden, außerdem können sie auch gleich initialisiert
werden:
my ( $var1 , $var2 );
my @array = (2 ,5 ,7);
innerhalb einer Subroutine:
sub drucke () {
my ( $var1 , $var2 );
...
}
5.3. Zugriff auf die Argumentvariablen in Subroutinen
77
5.3.2. Gültigkeitsbereich von lokalen Variablen
Durch die Deklaration mit my wird der Gültigkeitsbereich der Variablen eingeschränkt auf
den Block, innerhalb dessen sie deklariert worden ist. Nur innerhalb dieses Blockes kann
schreibend oder lesend auf sie zugegriffen werden. Lokale Variablen in einem Subroutinenblock sind nur innerhalb dieses Blocks verwendbar.
5.3.3. Übergabe des Argumentwerts an eine lokale Variable in der Subroutine
Im folgenden Beispiel wird gezeigt, wie die Elemente der Argumentvariablen an lokale
Variablen übergeben werden. Dabei gibt es je nach Datentyp der Argumentvariablen
verschiedene Möglichkeiten.
Beispiel 5.4: Übergabe der Argumente an Lokale Variablen
#!/ usr / bin / perl
# file : Subroutinen / uebergabe_lokal . perl
# zeigt die Übergabe an Lokale Variablen
{
use strict ' vars ';
my $wert1 =1;
my $wert2 =2;
my @liste =(1 ,2 ,3);
my % lex ;
$lex {" ich "}=3;
$lex {" du "}=5;
& drucke ( $wert1 );
& druckezwei ( $wert1 , $wert2 );
& druckeliste ( @liste );
& druckelexikon (% lex );
}
sub drucke ( $ ) {
my $w1 = @_[0];
print " Argument $w1 \ n ";
}
sub druckezwei ( $$ ) {
my ( $w1 , $w2 ) = @_;
print " Argument eins = $w1 \ n ";
print " Argument zwei = $w2 \ n ";
}
sub druckeliste ( @ ) {
my ( @werte ) = @_;
my $w ;
foreach $w ( @werte ) {
print " Argument = $w \ n ";
}
}
sub druckelexikon (%) {
my (% lexikon ) = @_;
my $w ;
foreach $w ( keys % lexikon ) {
print " Wort $w = $lexikon { $w }\ n ";
}
}
78
5. Subroutinen in Perl
5.4. Probleme bei der Übergabe von Argumenten an eine Subroutine
Werden in Perl an eine Subroutine Variablen übergeben, dann werden direkte Verweise
(sogenannte Aliases) auf die einzelnen Elemente der Argumentvariablen in der STACK
Listenvariable @_ gespeichert:
• bei Skalaren ein direkter Verweis auf die Variable
• bei Listen ein direkter Verweis auf jedes einzelne Element der Liste
• bei Hashes direkte Verweise auf die einzelnen Werte der Key/Value Paare
In Perl nennt man diese Technik: Linearisierung der Argumentvariablen.
Solange eine Subroutine nur mit einem Argument oder mehreren skalaren Argumenten
aufgerufen wird, tauchen keine Probleme bei der richtigen Verarbeitung der Argumente
innerhalb der Subroutine auf. Problematisch wird es aber, wenn eine Subroutine mit
mehreren Argumenten aufgerufen wird und die Argumente in beliebiger Reihenfolge Listen,
Skalare und/oder Hashes sind.
Der Grund liegt darin, dass Perl alle Argumentvariablen linearisiert, jedoch keine Information über die Art und Anzahl der Argumentvariablen in der STACK Listenvariable @_
speichert.
Beispiel 5.5: Linearisierung der Argumentvariablen:
my @gerade = (2 ,4 ,6);
my @ungerade = (1 ,3 ,5);
# Aufruf :
& erhoeheWert ( @gerade , @ungerade )
# in der STACK Listenvariable @_ stehen :
@ [0]
@ [1]
@ [2]
@ [3]
@ [4]
@ [5]
direkter
direkter
direkter
direkter
direkter
direkter
Verweis
Verweis
Verweis
Verweis
Verweis
Verweis
auf
auf
auf
auf
auf
auf
2 ,4 ,6 ,1 ,3 ,5
$gerade [0] ... also 2
$gerade [1] ... also 4
$gerade [2] ... also 6
$ungerade [0] ... also 1
$ungerade [0] ... also 3
$ungerade [0] ... also 5
Es besteht kein Hinweis auf die Anzahl der Elemente der beiden Listen und deshalb ist die
Zuweisung der STACK Listenvariablen in einer Subroutine an lokale Variablen nicht mehr
möglich:
sub erhoeheWert ( @@ ) {
my ( @ele_gerade , @ele_ungerade ) = @_;
...
}
# kann nicht funktionieren !!!
Das Problem der Linearisierung der Argumentvariablen kann nur gelöst werden, wenn:
• die Argumente nur aus Skalaren bestehen,
• bei Skalaren und einer Liste/Hash der Skalar als erstes Argument übergeben wird,
• bei Argumentvariablen mit unterschiedlichen Datentypen Referenzen auf Argumentvariablen übergeben werden.
5.4. Probleme bei der Übergabe von Argumenten an eine Subroutine
79
5.4.1. Übergabe der Argumentvariable als Referenz:
Die Übergabe von Argumenten in Form von Referenzen ist in Perl die einzige Möglichkeit,
das Problem der linearisierten Speicherung der Argumentvariablen auf der STACK Listenvariable @_ zu lösen. Intern wird diese Übergabeart dadurch realisiert, dass der Programmierer
das Unterprogramm mit einer Referenz auf die Argumentvariable im aufrufenden Programm
aufruft.
Nun kennt das Unterprogramm die Adresse der Argumentvariablen im aufrufenden Programm und kann deren Wert über den Zugriff der Referenz im aufrufenden Programm
lesen und auch verändern.
Damit in Perl die Referenz auf eine Variable an ein Unterprogramm übergeben wird, muss
man dem Variablennamen der Argumentvariable beim Aufruf einen Backslash voranstellen.
Über die Referenz kann man Perl nicht nur die Adresse eines Agruments ermitteln, sondern
auch den Datentyp der Argumentvariable.
Beispiel 5.6
my @namen = (" Hans " ," Gabi " ," Moni ");
& aendere (\ @namen ); # Argumentvariable ist eine Referenz auf das Array @namen
Der Subroutine &aendere wird eine Referenz übergeben: Durch Voranstellen eines Backslashs
vor den Variablennamen @namen wird aus der Liste @namen eine Referenz auf die Liste. Die
Subroutine bekommt als Argument die Referenz der Variablen und speichert sie in einer
lokalen Variablen:
Beim Zugriff auf eine Argumentvariable, die als Referenz übergeben wurde, muß die
Referenzvariable in geschweifte Klammern gesetzt werden und entsprechend des Datentyps
unter dem sie angesprochen werden soll der richtige Präfix des Datentyps vorangestellt
werden:
sub aendere ( @ ) {
my ( $liste_referenz ) = @_[0]; # speichern der Referenz
# Über die Referenz greift die Subroutine auf die Liste @namen zu
# Zugriff auf die gesamte Liste , Ausdrucken der Elemente :
print " @ { $liste_referenz }\ n ";
# Zugriff auf das erste Element der Liste , Ausdrucken des ersten Elements
print " Erster Wert $ { $liste_referenz }[0]\ n "; #
# Zugriff auf das erste Element der Liste : Ändern des Werts
$ { $liste_referenz }[0] = " Franz ";
}
80
5. Subroutinen in Perl
Beispiel 5.7: Referenzübergabe an lokale Variable
#!/ usr / bin / perl
# file : Subroutinen / uebergabe_lokal_referenz . perl
# zeigt die Übergabe an Lokale Variablen als Referenz
{
use strict ' vars ';
my $wert1 =1;
my $wert2 =2;
my @liste =(1 ,2 ,3);
my % lex ;
$lex {" ich "}=3;
$lex {" du "}=5;
& drucke (\ $wert1 );
& druckezwei (\ $wert1 ,\ $wert2 );
& druckeliste (\ @liste );
& druckelexikon (\% lex );
}
sub drucke (\ $ ) {
my ( $adresse ) = @_[0]; # speichere Adresse
my $w1 = $ { $adresse }; # Skalar
print " Argument $w1 \ n ";
}
sub druckezwei (\ $ \ $ ) {
my ( $w1 , $w2 ) = ( @_);
print " Argument eins = $ { $w1 }\ n ";
print " Argument zwei = $ { $w2 }\ n ";
}
sub druckeliste (\ @ ) {
my ( $adresse ) = @_[0];
my ( @werte ) = @ { $adresse };
my $w ;
foreach $w ( @werte ) {
print " Argument = $w \ n ";
}
}
sub druckelexikon (\%) {
my ( $adresse ) = @_[0];
my (% lexikon ) =%{ $adresse };
my $w ;
foreach $w ( keys % lexikon ) {
print " Wort $w = $lexikon { $w }\ n ";
}
}
5.5. Rückgabewerte von Subroutinen
81
5.4.2. Übergabe der Argumentvariablen als Referenz und Ändern des Wertes der
Argumentvariable:
Beispiel 5.8: Referenzübergabe und Ändern des Wertes der Argumentvariable
#!/ usr / bin / perl
# file : Subroutinen / uebergabe_lokal_referenz_aendern . perl
# zeigt die Übergabe an Lokale Variablen als Referenz
# und ändert den Wert der Argumentvariable
{
use strict ' vars ';
my $wert1 =1;
my $wert2 =2;
my @liste =(1 ,2 ,3);
my % lex ;
$lex {" ich "}=3;
$lex {" du "}=5;
& pluseins (\ $wert1 );
& pluseinsliste (\ @liste );
& pluseinslexikon (\% lex );
}
sub pluseins (\ $ ) {
my ( $wert_referenz ) = @_[0];
$ { $wert_referenz } =
$ { $wert_referenz } +100;
}
sub pluseinsliste (\ @ ) {
my ( $liste_referenz ) = @_[0];
my ( $anz_elem ) = scalar ( @ { $liste_referenz });
for ( my $i =0; $i < $anz_elem ; $i ++) {
$ { $liste_referenz }[ $i ] =
$ { $liste_referenz }[ $i ] +100;
}
}
sub pluseinslexikon (\%) {
my ( $hash_referenz ) = @_[0];
my (% lexikon ) =%{ $hash_referenz };
my $w ;
foreach $w ( keys % lexikon ) {
$ { $hash_referenz }{ $w } = $ { $hash_referenz }{ $w } + 100;
}
}
5.5. Rückgabewerte von Subroutinen
Ähnlich wie Funktionen in der Mathematik, können Subroutinen in Perl einen Wert an
das aufgerufene Programm über ihren Namen zurückgeben. Die Subroutine muss dann
innerhalb eines Ausdrucks aufgerufen werden.
z.B. in der Mathematik die Berechnung eines sinus Wertes:
Die Funktion sinus berechnet den sinus Werts seines Arguments und gibt das Ergebnis
über seinen Namen an den Aufrufer zurück:
y = sin (2.3)
oder
y = sin (2.3) * cos (4.0)
Welcher Wert zurückgegeben wird legt der Programmierer mit dem return statement im
Unterprogramm fest. Stößt die Abarbeitung einer Subroutine auf das return statement,
dann wird das Unterprogramm verlassen und der Wert des Ausdrucks der hinter dem
return steht als Ergebnis zurückgegeben.
In Perl können die Werte aller Ausdrücke zurückgegeben werden.
82
5. Subroutinen in Perl
Beispiel 5.9
return " hallo ";
return $erg ;
return @namen ;
# Rückgabe String " hallo "
# Rückgabe Wertes in der Variable $erg
# Rückgabe Liste @namen
5.6. Globale Variablen
Globale Variablen sind solche Variablen, auf die von jeder beliebigen Stelle im gesamten
Programm (d.h. auch von allen Subroutinen aus) sowohl lesend als auch schreibend
zugegriffen werden kann. Globale Variablen sollten wegen dieser Eigenschaft möglichst
vermieden werden, da man nie weiß, in welchem anderen Programmteil der Wert der
Variablen nicht eventuell geändert wird, sei es bewusst oder unbewusst (weil z.B. innerhalb
eines größeren Programms an anderer Stelle eine Variable gleichen Namens noch einmal
definiert wird). Dennoch sind globale Variablen manchmal sinnvoll, z.B. wenn sie wirklich
fast überall im Programm benötigt werden und andernfalls in praktisch jedem SubroutinenAufruf explizit als Argument übergeben werden müssten.
Beispiel 5.10: Subroutinen
#!/ usr / bin / perl
# file : Subroutinen / our . perl
# zeigt die Verwendung von Globalen Variablen
{
use strict ' vars ';
my $wert1 =1;
our $aufrufe =0; # Globale Variable
}
& drucke ( $wert1 );
& drucke ( $wert1 );
print " Anzahl der Aufrufe = $aufrufe \ n ";
sub drucke ( $ ) {
my $w1 = @_[0];
print " Argument $w1 \ n ";
$aufrufe = $aufrufe + 1; # Zugriff auf globale Variable
}
5.6.1. Die Verwendung von
our
Wird kein use strict verwendet, ist automatisch jede Variable, die nicht speziell mit my
deklariert wird, eine globale Variable. Wird jedoch (empfehlenswerterweise) use strict
verwendet, können globale Variablen nur mit our deklariert werden.
5.7. Rekursion bei Subroutinen
Man spricht von einer rekursiven Subroutine, wenn in den Abarbeitungsschritten, sprich
dem Rumpf der Subroutine, die Routine selbst wieder aufgerufen wird: Die Mathematik
spricht von einer rekursiven Funktion, wenn sie sich durch sich selbst definiert.
Die Verwendung der Rekursion in einer Programmiersprache hängt davon ab, ob ein STACKMechanismus implementiert ist, der sich von einem Aufruf zum nächsten Zwischenwerte
merken kann. Dieser STACK-Mechanismus ist in PERL definiert und somit kann die
Rekursion in PERL verwendet werden.
5.8. Exkurs: Übergabemechanismus in Perl im Detail (für den Spezialisten) :
83
Beispiel 5.11: Fakultät
Iterativ:
5! = 1 · 2 · 3 · 4 · 5
sub fak_iterativ ()
{
my $zahl = @_[0];
my $erg = 1;
my $i ;
if ( $zahl <= 0) { return 0 };
for ( $i =1; $i <= $zahl ; $i ++) {
$erg = $erg * $i ;
}
return $erg ;
}
Rekursiv:
Idee:
5!
120
= 5 * 4 * 3 * 2 * 1
= 5 * ( 4 * 3 * 2 * 1)
= 5 * 4!
4! = 4 * ( 3 * 2 * 1 )
= 4 * 3!
3! = 3 * ( 2 * 1 )
= 3 * 2!
2! = 2 * 1!
1! = 1 ( hier terminiert die Fakultät )
= 2 * 1
= 3 * 2
= 4 * 6
= 5 * 24
sub fak_rek ()
{
my $zahl = @_[0];
if ( $zahl ==1) {
return 1;
}
else {
return $zahl * & fak_rek ( $zahl -1);
}
}
5.8. Exkurs: Übergabemechanismus in Perl im Detail (für den
Spezialisten) :
Der Standardübergabemechanismus der Programmiersprache Perl ist eine Mischung von
„call by value“ und „call by reference“. Diese Mischung führt bei ungeübten Programmierern
schnell zu Verwirrung und Programmierfehlern und letztendlich zu einer Vermeidung von
selbstgeschriebenen Subroutinen.
In Perl erinnert die Aufrufart einer Subroutine an „call by value“, jedoch werden intern
dem Unterprogramm nicht eine Kopie der Argumente übergeben, sondern sogenannte
Aliases der einzelnen Argumente. Aliases sind Verweise auf die Speicheradresse einer
Variablen. Eine Subroutine kann somit lesend und schreibend auf seine Argumente zugreifen.
Problematisch wird diese Mischform, wenn Listen übergeben werden, da dann durch Perl
die Liste linearisiert wird und die Adressen der einzelnen Arrayelemente übergeben werden.
84
5. Subroutinen in Perl
Das Unterprogramm weiß gar nicht mehr, dass das Argument mit dem es aufgerufen wurde,
eine Liste war.
Erst mit der Version 5 der Programmiersprache Perl wurde der Übergabemechanismus
„call by reference“ eingeführt. Jetzt können Argumente mit ihren Adressen übergeben
werden. Das Unterprogramm bekommt die Information über den Variablentyp und über
die Adresse der aufrufenden Argumente. Skalare im aufrufenden Programm bleiben Skalare
im Unterprogramm und Listen bleiben im Unterprogramm Listen. Auf jedes Argument
kann über die Adresse zugegriffen werden.
Bei den Systemroutinen, die von Perl verwendet werden, müssen die Argumente laut
Definition der Subroutine übergeben werden. In den meisten Fällen ist dies bei Perl die
Aufrufart „call by value“.
Durch Vorstellen des Referenzoperators \ vor den Variablennamen wird in Perl automatisch
die Adresse einer Variable angesprochen.
$name
\ $name
Wert der Variable $name
Adresse der Variable $name
Um einer Subroutine Argumente nach der Aufrufart „call by reference“ zu übergeben, muss
man vor die Variablennamen der Subroutineargumenten immer ein Backslash schreiben.
5.8.1. Der STACK Speicher bei Subroutinenaufrufen
Damit zwischen Unterprogrammen und aufrufendem Programm Daten ausgetauscht werden
können, wird bei Perl ein spezieller Speicher reserviert, auf den sowohl das Unterprogramm
als auch das aufrufende Programm zugreifen kann. Dieser Speicherbereich heißt STACK.
Der STACK ist wie eine Liste organisiert und bekommt in Perl den reservierten Listenvariablennamen @_.
In die Liste @_ werden beim Aufruf des Unterprogramms automatisch die Werte bzw.
Adresse des Arguments bzw. der Argumentvariable, je nach Aufrufart, eingetragen. Das
Unterprogramm und das aufrufende Programm kann aus dieser Liste die Werte lesen.
Hier ein Beispiel zur Demonstration der Aufrufart „call by value“ und „call by reference“
Beispiel 5.12: „call by value“, „call by reference“
# Hauptprogramm
{
my $text = " hallo ";
my $name = " Sepp ";
my @farben = (" rot " ," grün " ," blau ");
}
Adressbuch des Hautprogramm:
NAME
$text
$name
@farben
ADRESSE
1000
2000
3000
3020
3040
TYP und WERT
Typ: Skalar, Wert=”Hallo”
Typ: Skalar, Wert=”Sepp”
Typ: Liste, Werte =
”rot”
”grün”
”blau”
5.9. Beispiel: Berechnung des Wochentags in Abhängikeit vom Datum
85
1.Fall: Aufruf einer Systemroutine ⇒ Aufrufsart = Call by Value
Die Argumente werden entweder als Konstante oder als Variable übergeben:
Aufruf:
print (" Hallo ");
NAME
STACKSPEICHER
ADRESSE
10000
TYP und WERT
Typ: Skalar, Wert=”Hallo”
get ( $name );
NAME
STACKSPEICHER
ADRESSE
10000
TYP und WERT
Typ: Skalar, Wert=”Sepp”, Alias auf 2000
print ( @farben );
NAME
STACKSPEICHER
ADRESSE
10000
TYP und WERT
Typ: Skalar, Wert=”rot”, Alias auf 3000
Typ: Skalar, Wert=”grün”, Alias auf 3020
Typ: Skalar, Wert=”blau”, Alias auf 3040
sort ( @liste );
NAME
STACKSPEICHER
ADRESSE
10000
TYP und WERT
Typ: Skalar, Wert=”rot”, Alias auf 3000
Typ: Skalar, Wert=”grün”, Alias auf 3020
Typ: Skalar, Wert=”blau”, Alias auf 3040
2. Fall: Aufruf einer eigenen Subroutine ⇒ Aufrufsart = Call by Reference
Es muss die Adresse der Argumente übergeben werden. Durch Voranstellen eines
Backslashs wird automatisch die Adresse einer Variable angesprochen.
Aufruf:
verändere_farben (\ @farben );
NAME
@_STACKSPEICHER
ADRESSE
10000
TYP und WERT
Typ: Liste, Wert=3000
konvertiere (\ $name ,\ $text );
NAME
STACKSPEICHER
ADRESSE
10000
10010
TYP und WERT
Typ: Skalar, Wert=1000
Typ: Skalar, Wert=2000
5.9. Beispiel: Berechnung des Wochentags in Abhängikeit vom Datum
Beispiel 5.13: Subroutinen
#!/ usr / bin / perl
# file :/ Subroutinen / wochentag . perl
# Berechnet den Wochentag in Abhängigkeit von einem Datum
use strict ' vars ';
86
5. Subroutinen in Perl
# # # # # # # ############# Teste Schaltjahr # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub schaltjahr ( $jahr ) {
my ( $jahr ) = @_;
return ( ( ( $jahr % 4 == 0 ) && ( $jahr % 100 != 0 ) )
|| ( $jahr % 400 == 0 ) );
}
# # # # # # # ############# Zähle Tage im Monat # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub tage_im_monat ( $monat , $jahr ) {
my ( $monat , $jahr ) = @_;
if (
$monat == 1 || $monat == 3 || $monat == 5 || $monat == 7
|| $monat == 8 || $monat == 10 || $monat == 12 ) {
return 31;
}
if ( $monat == 4 || $monat == 6 || $monat == 9 || $monat == 11 ) {
return 30;
}
}
if ( $monat == 2 ) {
if ( & schaltjahr ( $jahr ) ) {
return 29;
}
else {
return 28;
}
}
print (" Falscher Monat , Nummer = $monat \ n ");
return 0;
# # # # # # # ############# Zähle restliche Tage im Monat # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub restliche_tage_im_monat ( $tag , $monat , $jahr ) {
my ( $tag , $monat , $jahr ) = @_;
if ( $jahr > 1993 ) {
return $tag ;
}
else {
return ( & tage_im_monat ( $monat , $jahr ) - $tag );
}
}
# # # # # # # ############# Zähle restliche Tage im Jahr # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub restliche_tage_im_jahr ( $tag , $monat , $jahr ) {
my ( $tag , $monat , $jahr ) = @_;
my ( $summe , $index );
}
$summe = 0;
if ( $jahr > 1993 ) {
for ( $index = 1 ; $index < $monat ; $index ++ ) {
$summe = $summe + & tage_im_monat ( $index , $jahr );
}
return $summe + $tag ;
}
else {
for ( $index = 12 ; $index > $monat ; $index - - ) {
$summe = $summe + & tage_im_monat ( $index , $jahr );
}
return $summe + & restliche_tage_im_monat ( $tag , $monat , $jahr );
}
5.9. Beispiel: Berechnung des Wochentags in Abhängikeit vom Datum
87
# # ################## Zähle Tage im Jahr # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub tage_im_jahr ( $jahr ) {
my ( $jahr ) = @_;
if ( & schaltjahr ( $jahr ) ) {
return 366;
}
else {
return 365;
}
}
# # ################## Zähle Tage # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub anzahl_der_tage ( $tag , $monat , $jahr ) {
my ( $tag , $monat , $jahr ) = @_;
my ( $summe , $index );
$summe = 0;
if ( $jahr > 1993 ) {
for ( $index = 1994 ; $index < $jahr ; $index ++ ) {
$summe = $summe + & tage_im_jahr ( $index );
}
return ( $summe + & restliche_tage_im_jahr ( $tag , $monat , $jahr ) );
}
else {
for ( $index = 1993 ; $index > $jahr ; $index - - ) {
}
}
$summe = $summe + & tage_im_jahr ( $index );
}
return ( $summe + & restliche_tage_im_jahr ( $tag , $monat , $jahr ) );
# # ################## Bestimme Wochentag # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub wochentag_nummer ( $tag , $monat , $jahr ) {
my ( $tag , $monat , $jahr ) = @_;
if ( $jahr > 1993 ) {
return ( & anzahl_der_tage ( $tag , $monat , $jahr ) % 7 );
}
else {
return ( ( 7 - ( & anzahl_der_tage ( $tag , $monat , $jahr ) % 7 ) ) % 7 );
}
}
### Hauptprogramm :
{
my ( $tag , $tage , $jahr , $monat , $gesuchter_tag );
print (" Hallo , hier ist Wochentag \ n ");
print (" Bitte Jahr eingeben > > > >");
$jahr = < stdin >;
chomp ( $jahr );
if ( & schaltjahr ( $jahr ) != 0 ) {
print (" Schaltjahr \ n ");
}
else {
print (" Kein Schaltjahr \ n ");
}
print (" Bitte Monat eingeben > > > >");
$monat = < stdin >;
chomp ( $monat );
$tage = & tage_im_monat ( $monat , $jahr );
print (" Anzahl der Tage im Monat $monat = $tage \ n ");
88
5. Subroutinen in Perl
print (" Bitte Tag eingeben > > > >");
$tag = < stdin >;
chomp ( $tag );
print (" Der gesuchte Wochentag ist ein ");
$gesuchter_tag = & wochentag_nummer ( $tag , $monat , $jahr );
if
if
if
if
if
if
if
(
(
(
(
(
(
(
$gesuchter_tag
$gesuchter_tag
$gesuchter_tag
$gesuchter_tag
$gesuchter_tag
$gesuchter_tag
$gesuchter_tag
==
==
==
==
==
==
==
0
1
2
3
4
5
6
)
)
)
)
)
)
)
{
{
{
{
{
{
{
print (" Freitag "); }
print (" Samstag "); }
print (" Sonntag "); }
print (" Montag "); }
print (" Dienstag "); }
print (" Mittwoch "); }
print (" Donnerstag "); }
print ("\ n ");
## Falls Library da ist :
## use Date :: Calc qw ( Day_of_Week Day_of_Week_to_Text Language Decode_Language );
################ Als Libraryaufruf ...
# $gesuchter_tag = Day_of_Week ( $jahr , $monat , $tag );
# Language ( Decode_Language (" Deutsch "));
# print " Aus der Libray " , Day_of_Week_to_Text ( $gesuchter_tag ) ," \ n ";
# # # # # # # # # # # # # # # # # # # # # # # # # # # Ende # # # # # # # # # # # # # # # # # # # # # # # # # # # #
}
6. Aufgaben und Lösungen
6.1. Aufgabe: größte/kleinste Zahl
Schreiben Sie ein Perl Programm, das den Benutzer auffordert 3 Zahlen einzulesen und die
größte und kleinste Zahl der drei eingegebenen Zahlen ausgibt.
#!/ usr / bin / perl -w
# file : / AufgabenLoesungen / groeste - kleinsteZahl . perl
# Auffinden der groesten bzw . kleinsten Zahl
use strict ;
{
my ( $a , $b , $c , $groesste_zahl , $kleinste_zahl );
print (" Bitte drei Zahlen eingeben .\ n ");
print (" Zahl 1: ");
$a = < >;
print (" Zahl 2: ");
$b = < >;
print (" Zahl 3: ");
$c = < >;
chomp ( $a , $b , $c );
}
if ( $a >= $b ) {
$groesste_zahl = $a ;
$kleinste_zahl = $b ;
if ( $c > $a ) {
$groesste_zahl = $c ;
}
if ( $c < $b ) {
$kleinste_zahl = $c ;
}
}
if ( $b > $a ) {
$groesste_zahl = $b ;
$kleinste_zahl = $a ;
if ( $c > $b ) {
$groesste_zahl = $c ;
}
if ( $c < $a ) {
$kleinste_zahl = $c ;
}
}
print (" Groesste Zahl : $groesste_zahl \ n ");
print (" Kleinste Zahl : $kleinste_zahl \ n ");
6.2. Aufgabe: Alphabetischer Vergleich
Lesen Sie zwei Zeichenketten ein und geben Sie die alphabetisch ’kleinere’ und die alphabetisch ’größere’ Zeichenkette aus.
$a = < >;
$b = < >;
89
90
6. Aufgaben und Lösungen
if ( $a lt $b )
{
print (" alphabetisch
print (" alphabetisch
}
else
{
print (" alphabetisch
print (" alphabetisch
kleinere Zeichenkette : $a ");
größere Zeichenkette : $b ");
kleinere Zeichenkette $b ");
größere Zeichenkette : $a "); }
6.3. Aufgabe: Fakultät (iterativ, rekursiv)
Berechnen Sie die Fakultät einer Zahl: Das Programm soll nach einer Zahl fragen und die
Fakultät dieser Zahl berechnen. Beispiel: Die Fakultät der Zahl 5 = 5 · 4 · 3 · 2 · 1
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / fakultaet . pl
# Iterative Lösung der Fakultät
use strict ;
{
my ( $eingabe , $fakultaet , $zaehler );
print (" Gib eine Zahl ein : ");
$eingabe = < >;
chomp $eingabe ;
$zaehler
= 1;
$fakultaet = 1;
while ( $zaehler <= $eingabe ) {
$fakultaet = $fakultaet * $zaehler ;
$zaehler ++;
}
print (" Die Fakultaet von $eingabe ist $fakultaet \ n ");
}
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / fakultaetRekursiv . pl
# Rekursive Lösung der Fakultät
use strict ;
{
my ( $eingabe , $result );
print (" Gib eine Zahl ein : ");
$eingabe = < >;
chomp $eingabe ;
$result = & fak ( $eingabe );
print (" Die Fakultaet von $eingabe ist $result \ n ");
}
#######################################
sub fak ( $ ) {
my $zahl = $_[0];
if ( $zahl == 1 ) {
print (" letzter Aufruf \ n ");
print ("..... Terminiere mit Eins \ n ");
return 1;
}
else {
return $zahl * & fak ( $zahl - 1 );
}
}
6.4. Aufgabe: Einlesen einer Rechenaufgabe
91
6.4. Aufgabe: Einlesen einer Rechenaufgabe
Wie lautet ein Perl-Programm, das dem Benutzer 4 leichte Rechenaufgaben in Form eines
Textes auf das Terminal schreibt und den Benutzer nach jeder Rechenaufgabe auffordert,
das Rechenergebnis einzugeben?
Das Programm liest die Eingabe und überprüft, ob das Ergebnis stimmt.
Das Programm soll die Anzahl der richtigen Antworten zählen und am Schluss ausgeben,
wieviele Ergebnisse richtig waren.
Falls alle vier Aufgaben richtig gerechnet wurden, soll ein besonderes Lob auf das Terminal
geschrieben werden.
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / einlesenRechen . pl
# Einlesen einer Rechenaufgabe
use strict ;
{
my ( $zahl , $richtig );
$richtig = 0;
print (" AUSGABE : Welchen Wert hat 2+2?\ n ");
print (" EINGABE : ");
$zahl = < >;
chomp $zahl ;
if ( $zahl == ( 2 + 2 ) ) {
$richtig ++;
}
print (" AUSGABE : Welchen Wert hat 2*3?\ n ");
print (" EINGABE : ");
$zahl = < >;
chomp $zahl ;
if ( $zahl == ( 2 * 3 ) ) {
$richtig ++;
}
print (" AUSGABE : Welchen Wert hat 10/5?\ n ");
print (" EINGABE : ");
$zahl = < >;
chomp $zahl ;
if ( $zahl == ( 10 / 5 ) ) {
$richtig ++;
}
print (" AUSGABE : Welchen Wert hat 3 + 4 + 5?\ n ");
print (" EINGABE : ");
$zahl = < >;
chomp $zahl ;
if ( $zahl == ( 3 + 4 + 5 ) ) {
$richtig ++;
}
}
if ( $richtig == 4 ) {
print (" Du bist der Wahnsinn ! So schwere Aufgaben ...\ n ");
}
else {
print (" $richtig Aufgaben richtig gelöst .\ n ");
}
92
6. Aufgaben und Lösungen
6.5. Aufgabe: Wörter mit Selbstlauten extrahieren
Schreiben Sie ein Perl Programm, das eine Datei selbstlaute_woerter.txt erzeugt, in die
alle Wörter aus der Datei wortliste.txt kopiert werden, die mit einem Selbstlaut a,e,i,o,u
beginnen.
Tipp: Lesen Sie wieder jedes Wort aus der Wortliste und zerlegen Sie jedes Wort mit split.
Testen sie ob der erste Buchstabe ein Selbstlaut ist.
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / selbstlaute . pl
# Wörter mit Selbstlauten extrahieren
use strict ;
{
my ( $dateiname , $ausgabe , $zeile );
my ( @buchstaben );
$dateiname = " wortliste . txt ";
$ausgabe
= " selbstlaute_woerter . txt ";
open ( DATEI , $dateiname );
open ( AUSGABE , " > $ausgabe ");
}
while ( $zeile = < DATEI > ) {
chomp $zeile ;
@buchstaben = split ( // , $zeile );
if (
( lc ( $buchstaben [0]) eq " a "
|| ( lc ( $buchstaben [0]) eq " e "
|| ( lc ( $buchstaben [0]) eq " i "
|| ( lc ( $buchstaben [0]) eq " o "
|| ( lc ( $buchstaben [0]) eq " u "
{
print AUSGABE " $zeile \ n ";
print " $zeile \ n ";
}
}
close DATEI ;
close AUSGABE ;
)
)
)
)
) )
6.6. Aufgabe: Buchstaben zählen
Schreiben Sie ein Perl Programm, das die Buchstaben in der Datei wortliste.txt liest und
die Anzahl der Buchstaben zählt und ausgibt.(Tipp: Verwenden Sie die Perl Routine length)
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / buchstaben . pl
# Buchstaben zählen
use strict ;
{
my ( $dateiname , $zeile , $buchstabenzahl , $gesamtanzahl );
$dateiname
= " wortliste . txt ";
$gesamtanzahl = 0;
open ( DATEI , $dateiname );
while ( $zeile = < DATEI > ) {
chomp $zeile ;
$buchstabenzahl = length ( $zeile );
$gesamtanzahl
= $gesamtanzahl + $buchstabenzahl ;
}
close DATEI ;
6.7. Aufgabe: Passwort abfragen
}
93
print (" Die Anzahl der Buchstaben betraegt $gesamtanzahl \ n ");
6.7. Aufgabe: Passwort abfragen
Schreiben Sie ein Passwort-Perl Programm: In der Datei passwd.txt steht das Passwort.
Das Perl Programm soll aus dieser Datei das aktuelle Passwort lesen und den Benutzer
maximal fünf Mal nach dem Passwort fragen.
Jedes Passwort, auch ein falsches, das der Benutzer eingibt, soll in der Datei passwd.log
gespeichert werden.
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / passwort . pl
# Passwort abfragen
use strict ;
{
my ( $dateiname , $zeile , $ausgabedatei , $passwort , $zaehler , $geraten );
my ( @letters );
$dateiname
= " passwd . txt ";
$ausgabedatei = " passwd . log ";
open ( DATEI , $dateiname );
while ( $zeile = < DATEI > ) {
chomp $zeile ;
$passwort = $zeile ;
}
close DATEI ;
open ( AUSGABE , " > $ausgabedatei " );
print (" Bitte Passwort eingeben :\ n ");
$geraten = < STDIN >;
chomp $geraten ;
print AUSGABE (" $geraten \ n ");
$zaehler = 1;
while ( ( $zaehler < 5 ) && ( $geraten ne $passwort ) ) {
print (" Falsch . Naechster Versuch :\ n ");
$geraten = < STDIN >;
chomp $geraten ;
print AUSGABE (" $geraten \ n ");
$zaehler ++;
}
}
if ( $geraten eq $passwort ) {
print (" Richtig .\ n ");
}
close AUSGABE ;
94
6. Aufgaben und Lösungen
6.8. Aufgabe: Wörter mit drei Buchstaben
Speichern Sie alle drei Buchstaben lange Wörter des Textes info.txt in der Datei drei.txt.
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / dreiBuchstaben . pl
# Ausgeben von Strings in eine Textdatei
use strict ;
{
my ( $text , $zeile , $zaehler , $ausgabe );
my ( @woerter );
my % anzahl ;
$text
= " info . txt ";
$ausgabe = " drei . txt ";
open ( INFO , $text );
open ( DREI , " > $ausgabe " );
}
while ( $zeile = < INFO > ) {
chomp $zeile ;
@woerter = split ( /[ ,. ;:]+/ , $zeile );
foreach my $wort ( @woerter ) {
if ( length ( $wort ) == 3 ) {
print DREI (" $wort \ n ");
}
}
}
close INFO ;
close DREI ;
print (" Ausgabe in $ausgabe geschrieben .\ n ");
6.9. Aufgabe: Wörter zählen
Erweitern Sie das vorige Perl-Programm, um alle kleingeschrieben und großgeschriebenen
Wörter in einer Datei mit UTF8-codierung zu zählen. Bitte setzen Sie dabei alle Kanäle
auf UTF8.
#!/ usr / bin / perl
# file :/ AufgabenLoesungen / kleinWoerter . pl
# Berechnen von groß - bzw . kleingeschriebene Wörter einer Textdatei
use strict ;
{
my ( $zeile , $klein , $gross );
$gross = 0;
$klein = 0;
my ( @woerter , @buchstaben );
binmode ( STDIN , ": utf8 " ); # Setzt STDIN auf utf -8
binmode ( STDOUT , ": utf8 " ); # Setzt STDOUT auf utf -8
open ( LESEN , " <: utf8 " , " sz_artikel . txt " );
while ( $zeile = < LESEN > ) {
chomp $zeile ;
@woerter = split ( /[ ,. ;:\(\)\/\*\"]+/ , $zeile );
foreach my $wort ( @woerter ) {
@buchstaben = split ( // , $wort );
if ( $buchstaben [0] =~ /[ a - zäöü ]/ ) {
$klein ++;
}
if ( $buchstaben [0] =~ /[ A - ZÄÖÜ ]/ ) {
$gross ++;
}
}
6.10. Aufgabe: Split von Zeilen und Wortliste
}
95
}
close LESEN ;
print (" Gross geschrieben : $gross Woerter \ n ");
print (" Klein geschrieben : $klein Woerter \ n ");
6.10. Aufgabe: Split von Zeilen und Wortliste
Lesen Sie die Datei zeilenweise ein und verwenden Sie die Perl Routine split um die Zeilen
des Artikels in Wörter aufzuspalten.
#!/ usr / bin / perl
# file :/ AufgabenLoesungen / zeilenSplit . perl
# Split von Zeilen und Wortliste
use strict ;
{
my ( $zeile );
my ( @woerter );
open ( LESEN , " sz_artikel . txt " );
}
while ( $zeile = < LESEN > ) {
chomp $zeile ;
@woerter = split ( /[ ,. ;:\(\)\/\*\"]+/ , $zeile );
foreach my $wort ( @woerter ) {
print " $wort \ n ";
}
}
close ( LESEN );
# (*) siehe unten
Zeichen wie (, ), /, *, \ oder ” haben eine eigene Bedeutung im regulären Ausdruck. Diese
Metabedeutung wird durch einen vorangestellten Backslash aufgehoben.
Erweitern Sie das Perl-Programm um alle Wörter des sz Artikels in einen Hash einzufügen
und alphabetisch sortiert auszugeben. Die Wörter sollen alphabetisch sortiert in der Datei
wort_sort.txt gespeichert werden.
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / zeilenSplitHash . perl
# Erzeugen einer Frequenzliste
use strict ;
{
my ( $zeile );
my ( @woerter );
my % worthash ;
open ( LESEN , " sz_artikel . txt " );
open ( SORT , " > wort_sort . txt " );
while ( $zeile = < LESEN > ) {
chomp $zeile ;
@woerter = split ( /[ ,. ;:\(\)\/\*\"]+/ , $zeile );
foreach my $wort ( @woerter ) {
$worthash { $wort }++;
}
}
close LESEN ;
}
foreach my $wort ( sort keys % worthash ) {
print SORT " $wort \ n ";
}
print (" Sortiert in wort_sort . txt gespeichert !\ n ");
close SORT ;
96
6. Aufgaben und Lösungen
6.11. Aufgabe: Frequenzliste
Schreiben Sie ein Programm, das den Artikel der sz.txt liest und die 10 am häufigsten vorkommenden grossgeschriebenen Wörter und die 10 am häufigsten vorkommenden
kleingeschriebenen Wörter ausgibt.
Tipp: Füllen Sie zwei Hashes, einen für die kleingeschriebenen Wörter und einen für die
großgeschriebenen Wörter. Um zu entscheiden, ob ein Wort groß oder kleingeschrieben
wird, verwenden Sie in einer if Anfrage reguläre Ausdrücke (siehe script)
#!/ usr / bin / perl -w
# file :/ AufgabenLoesungen / haeufigsten10 . pl
# Top 10 Wörter auflisten mithilfe von Frequenzliste
use strict ;
{
my ( $zeile , $zaehler );
my ( @woerter , @buchstaben );
my ( % hash_klein , % hash_gross );
open ( LESEN , " sz_artikel . txt " );
while ( $zeile = < LESEN > ) {
chomp $zeile ;
@woerter = split ( /[ ,. ;:\(\)\/\*\"]+/ , $zeile );
foreach my $wort ( @woerter ) {
@buchstaben = split ( // , $wort ) unless $wort eq "";
if ( $buchstaben [0] =~ /[ a - zäöü ]/ ) {
$hash_klein { $wort }++;
}
if ( $buchstaben [0] =~ /[ A - ZÄÖÜ ]/ ) {
$hash_gross { $wort }++;
}
}
}
$zaehler = 0;
print " Klein geschrieben : \ n ";
foreach my $kleines_wort ( sort { $hash_klein { $b } <= > $hash_klein { $a } }
keys % hash_klein )
{
if ( $zaehler != 10 ) {
print (" $kleines_wort = $hash_klein { $kleines_wort }\ n ");
$zaehler ++;
}
}
$zaehler = 0;
print "\ nGross geschrieben : \ n ";
foreach my $gross_wort ( sort { $hash_gross { $b } <= > $hash_gross { $a } }
keys % hash_gross )
{
if ( $zaehler != 10 ) {
print (" $gross_wort = $hash_gross { $gross_wort }\ n ");
$zaehler ++;
}
}
}
7. Linux
7.1. Einführung in Linux
7.1.1. Einleitung
Nach Bearbeitung dieses Kapitels können Sie grundlegende Eigenschaften von Linux
Systemen verstehen.
7.1.2. Eigenschaften
• Multi-User-Betrieb
Am System können mehrere Benutzer gleichzeitig arbeiten. Sie werden über den
Benutzernamen unterschieden.
• Multi-Tasking
Am System können mehrere Programme gleichzeitig arbeiten.
• Timesharing
Programme werden über Prioritäten verwaltet und bekommen abwechselnd die
CPU(s).
• Interaktivität
Jeder Benutzer kann mit einem Terminal interaktiv arbeiten.
• Hierarchisches Dateisystem
Alle Dateien werden über eine Baumstruktur verwaltet.
• Benutzerschnittstelle (Shell)
Der Benutzer kommuniziert mit Linux über eine Kommandosprache, die Shell
heißt.
• grafische Benutzerschnittstelle(GUI)
z.B. via X11-Server, KDE und Gnome.
• Programmentwicklung
Unter Linux gibt es zahlreiche Werkzeuge zur Programmerstellung.
• Textverarbeitung
Unter Linux gibt es zahlreiche Programme zur Textverwaltung.
• Netzwerkunterstützung
Jedes Linux kann in einem TCP/IP Netzwerk arbeiten. Unterstützt netzwerkweite Dateisysteme (NFS), mail, Programme usw.
• Kernel
Kontrolliert die Hardware
97
98
7. Linux
Memory Management Unit
CPU Vergabe über Prioritäten
Geräte Ein/Ausgabe
• System Dienste
Arbeiten direkt mit dem Kernel zusammen
Die Systemdienste stehen als C-Programme zur Verfügung.
• Dienstprogramme
Komplexe Programme als Linux Befehle
• Benutzerschnittstelle
Es stehen verschiedene Shells zur Verfügung :
bash, zsh
• Grafische Benutzerschnittstelle
basierend auf X11: KDE, Gnome und andere
Abbildung 7.1.: Graphische Darstellung des LINUX-Systems
7.2. Verwalten von Dateien Teil 1
7.2.1. Einleitung
Nach Bearbeitung dieses Kapitels können Sie :
• Das Linux Dateisystem verstehen.
• Verzeichnisse, Dateien und Gerätedateien unterscheiden.
• Die wichtigsten Aufgaben zum Verwalten von Dateien durchführen.
• Dateibezeichnungen korrekt eingeben.
7.2. Verwalten von Dateien Teil 1
99
7.2.2. Das Linux Dateisystem
7.2.2.1. Der hierarchische Dateibaum
Alle Linux Dateien sind streng hierarchisch baumartig organisiert. Der Ausgangspunkt des
Dateibaums ist das root Directory ”/”, auch Stammverzeichnis genannt, das auf weitere
Dateien oder Verzeichnisse verweist. Es gibt keine Laufwerksbuchstaben.
Bei Linux gibt es Standardverzeichnisse in denen Dateien für spezielle Aufgaben zusammengefasst sind. Wichtige Standardverzeichnisse und die Aufgaben ihrer Dateien sind:
Verzeichnis
/
/ sbin /
/ bin /
/ boot /
/ dev /
/ home /
/ root /
/ tmp /
/ usr /
/ usr / bin /
/ usr / X11R6 / bin /
/ usr / src /
/ var /
/ var / log /
/ proc /
/ opt /
/ mnt /
/ media
/ etc /
/ etc / init . d /
/ etc / X11 /
/ lib /
/ usr / lib /
kurze Beschreibung
root - Verzeichnis ( Basisverzeichnis )
Programme für den Systemverwalter
allgemeine Kommandozeilen - Befehle ( GNU - Programme )
Verzeichnis für Startdateien und den Kernel
Gerätedateien ( für Tastatur , Maus , Modem ,
Festplatte , CDROM , ...)
Benu tzer verz eichn isse
Verzeichnis des Systemverwalters
temporäre Dateien
Dateien / Programme für die Benutzer
Anwendungsprogramme für die Benutzer
Anwendungsprogramme für die grafische Oberfläche
Quellcodes ( z . B . vom Linux - Kernel )
Verzeichnis für sich ändernde Daten
( Mailverzeichnis , Druckerspooler , ...)
Protokoll - Dateien
Systeminformationen ; Schnittstelle zum Kernel
optionale Programme ( teilweise KDE , Firefox )
Mount - Point für Disketten , CD - ROMs , etc ...
Mount - Point für externe Festplatten , USB - Sticks ,
CD - ROMs usw .
systemweite Konf igur atio nsdat eien
Start -/ Stopscripte der Systemdienste
Konf igur atio nsdat eien von xorg
allgemeine Programm - Bibliotheken ( Programmlader ,
Hauptbibliothek glibc )
Programm - Bibliotheken für Anwendungsprogramme
Jeder User arbeitet zu jedem Zeitpunkt in einem Working Directory, das er mit dem Befehl
cd (change Directory) ändern und mit dem Befehl pwd (print Working Directory) ausgeben
kann. Unter Linux können Verzeichnisse deviceübergreifend auf beliebigen Datenträgern
abgespeichert werden. Der Systemadministrator bindet die Verzeichnisse an eine beliebige
Stelle des Dateibaumes ein (mount), wobei sich an der hierarchischen Dateistruktur nichts
ändert. Der User merkt auch nicht auf welcher physikalischen Platte er momentan arbeitet.
(Abfrage mit ”df .”)
Eine aktuelle Zusammenfassung des hierarchischen Dateisystems findet sich unter
https://de.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
7.2.2.2. Verzeichnisse, Dateien und Gerätedateien
In Linux gibt es
• gewöhnliche Dateien
Textdateien, am Terminal ausgebbar
Binärdateien, Programmdateien
• Verzeichnisse
Sammlung von anderen Dateien, die selbst Verzeichnisse sein können
100
7. Linux
• spezielle Dateien
Gerätedateien in denen die Routinen des Linux Kernels abgespeichert sind, die die Einund Ausgabe auf physikalische Geräte realisieren. Jedes Gerät hat für jede Schnittstelle
ein eigenes Devicefile.
Wichtige Gerätedateien sind :
/ dev / sd *
/ dev / hd *
/ dev / console
/ dev / tty01
/ dev / null
/ dev / sr *
/ dev / zero
: Festplatten , allgemein Datenträger ,
also auch usb - memory - sticks
: Festplatten , mit alten Treiber /p - ata
: System Konsole
: asynchrones Terminal
: Null - Device
: CD - Rom
: Zero - Device
7.2.3. Fallbeispiel zum Verwalten von Dateien
7.2.3.1. Das Anlegen von Dateien
In den nächsten Kapiteln werden Datei- und Verzeichnisoperationen anhand eines Fallbeispiels erklärt. Es gibt 3 Studenten: meier, huber und schoch
Es ergibt sich folgende hierarchische Dateistruktur.
Abbildung 7.2.: Hierarchische Dateistruktur von LINUX
Zum Anlegen von Dateien gibt es unter Linux die Möglichkeit, die Terminaleingabe in
eine Datei umzuleiten (Befehl cat) oder einen Texteditor aufzurufen. Achtung : Unter
Linux werden ältere Versionen von Dateien nicht automatisch gesichert, sondern stets
überschrieben.
Beispiel 7.1
> pwd
/ mounts / users / student / meier
Im Bereich Holzbau soll für den Dachbau eine neue Datei dach angelegt werden:
Beispiel 7.2
> cat > text1 . txt
> touch text2 . txt
: Schreibt Terminaleingabe in die Datei
text1 . txt ,
Beenden der Eingabe mit CTRL d
: Kreiert eine leere Datei mit dem Namen
text2 . txt
7.2. Verwalten von Dateien Teil 1
101
7.2.3.2. Das Anzeigen von Inhaltsverzeichnissen
Der Inhalt des Verzeichnisses wird mit dem Befehl ls ausgegeben:
wichtige Optionen des Befehls ls:
-a listet auch die verborgenen Dateien (der Dateiname beginnt mit einem Punkt) im
Verzeichnis auf.
-l langes (ausführliches) Ausgabeformat
In jedem Verzeichnis gibt es immer die zwei verborgenen Dateien:
. Zeigt auf das eigene Verzeichnis
.. Zeigt auf das Elternverzeichnis
-F hängt dem Dateiname ein Metazeichen an, das den Dateityp anzeigt:
\ für Verzeichnis
* für ausführbar
Beispiel 7.3
Benutzer huber nach dem einloggen:
> pwd
/ mounts / users / student / huber
> ls
briefe seminar text . txt
> ls - aF
./ ../ briefe / seminar / text . txt
7.2.3.3. Länge und Zeichenkonventionen von Dateinamen
Bei Datei- und Verzeichnisnamen können mit 254 Bytes nicht unbedingt 254 Stellen
genutzt werden. Sonderzeichen und Umlaute sind nach Möglichkeit zu vermeiden aber
nicht ausgeschlossen (Dateiname wird utf-8 codiert). Groß- und Kleinschreibung wird
unterschieden(case sensitiv). Ein Name sollte nicht mit einem Punkt (nur bei explixiter
verborgener Datei) oder mit einem Minus beginnen (Name könnte als Befehlsoption
behandelt werden). Im Dateinamen sollte kein ”*” stehen.
Wenn sich Sonderzeichen nicht vermeiden lassen, müssen sie mit besonderer Sorgfalt
eingegeben werden:
z.B. ”\ ” für Space.
Der Schrägstrich / ist verboten da er als Trenner im Pfadnamen fungiert.
7.2.3.4. Das Löschen von Dateien
Unter Linux können Dateien (Befehl rm) und Verzeichnisse mit ihren Unterverzeichnissen
(Befehl rm -r) gelöscht werden.
Beispiel 7.4
Es sollen die Datei text.txt und das Verzeichnis seminar mit allen Dateien gelöscht werden:
> pwd
/ mounts / users / student / huber
> rm text . txt
> rm -r seminar
102
7. Linux
Um Dateien zu entfernen, deren Namen mit ”-” beginnen, z.B. ”foo”, verwenden Sie eine
der folgenden Anweisungen:
> rm -- - foo
> rm ./ - foo
7.2.3.5. Das Anzeigen von Dateien
Jede Textdatei kann am Bildschirm mit automatischem Scrolling (Befehl cat) oder bildschirmweise (Befehl less, more) ausgegeben werden :
Beispiel 7.5
> pwd
/ mounts / users / student / huber
Ausgabe der Datei Fenster am Bildschirm
automatisches Scrolling:
> cat text . txt
bildschirmweise:
> more text . txt
bildschirmweise, mit verbesserter Positioniermöglichkeit als more:
> less text . txt
7.2.3.6. Das Verwalten von Verzeichnissen
Innerhalb von Verzeichnissen können beliebige neue Verzeichnisse kreiert (Befehl mkdir)
oder, falls sie leer sind, gelöscht (Befehl rmdir) werden. Der Benutzer kann jedes Verzeichnis
zu seinem Working Directory machen (Befehl cd).
Beispiel 7.6
das momentane Verzeichnis ist :
> pwd
/ mounts / users / student / huber
Ein Verzeichnis loesungen soll kreiert werden:
> mkdir loesungen
Das Working Directory soll auf loesungen gesetzt werden:
> cd loesungen
Der Benutzer will in sein Home Verzeichnis springen:
> cd
Relative und absolute Datei- oder Verzeichnisbezeichnungen
Linux kann Dateien über relative oder absolute Dateibezeichnungen ansprechen. Während
absolute Dateinamen die Dateihierarchie, ausgehend vom Rootdirectory im Namen auflisten,
beginnt die Auflistung der Unterverzeichnisse bei relativen Bezeichnungen erst ab dem
momentanen Working Directory.
7.2. Verwalten von Dateien Teil 1
103
Beispiel 7.7
> pwd
/ mounts / users / student / huber
absolute Dateibezeichnung:
> ls / mounts / users / student / huber / briefe
relative Dateibezeichnung:
> ls briefe
7.2.3.7. Das Kopieren und Umbenennen von Dateien
Unter UNIX kann eine Datei in eine andere kopiert werden (Befehl cp). Dabei werden
bestehende Dateien überschrieben. Mehrere Dateien können mit einem cp Befehl nur in
Verzeichnisse kopiert werden. Sollen die Namen von Dateien oder Verzeichnissen geändert
werden, so gibt es unter UNIX den Befehl mv (=move).
Beispiel 7.8
> pwd
/ mounts / users / student / huber
Alle Dateien und alle Unterverzeichnisse aus dem Verzeichnis seminar/ sollen in das
Verzeichnis seminar_alt/ kopiert werden:
> cp -r seminar seminar_alt
Alle Dateien aber keine Unterverzeichnisse aus dem Verzeichnis seminar/ sollen in das
Verzeichnis letzte/ kopiert werden:
> mkdir letzte
> cd seminar
> cp * ../ letzte
Alle Dateien und alle Unterverzeichnisse aus dem Verzeichnis letzte/ im Verzeichnis seminar/
sollen in das neue Verzeichnis /sicherung kopiert werden:
> mkdir ../ sicherung
> cp -r ../ letzte / seminare
../ sicherung
Das Verzeichnis letzte soll in aller_letzte umbenannt werden:
> mv letzte aller_letzte
7.2.4. Dateinamen und der Einsatz von Wildcards
7.2.4.1. Einsatz von Wildcards
Um in einem Befehl mehrere Verzeichnisse oder Dateien anzusprechen, können in den
Namen Wildcards verwendet werden.
Wichtige Wildcards sind * (steht für alles, außer einem Punkt am Anfang der Datei) und ?
(steht für einen Buchstaben)
Beispiel 7.9
> pwd
/ mounts / users / student / huber
Alle Dateien in allen Verzeichnissen, in deren Namen einf vorkommt, sollen aufgelistet
werden :
> ls */*/* einf *
104
7. Linux
Alle Dateien, die einen sechs Buchstaben langen Namen haben, sollen aufgelistet werden :
> ls */*/??????
7.2.4.2. Verwendung von Sonderzeichen
Bestimmte Sonderzeichen in Dateinamen werden von der Shell interpretiert und zur
Dateinamengenerierung verwendet.
\c
Aufheben der Dateinamen Generierung für den nachfolgenden Buchstaben c
\
am Ende Eine Zeile fordert eine Folgezeile
””
Aufheben der Dateinamenexpandierung für den eingeschlossenen String
tilde (˜) Die bash (Shell) ersetzt die tilde durch das Homedirectory
Beispiel 7.10
Ein Dateinname enthät ein Leerzeichen : Kreieren der Datei Mathe V1
> cat > " Mathe V1 "
Kreieren und Ansprechen der Datei Mathe*
> cat > Mathe \*
> ls Mathe \*
7.2.5. Das Wichtigste in Kürze
• Das Linux Dateisystem ist ein hierarchisches, baumartiges Dateisystem, bei dem
Verzeichnisse Device-übergreifend abgespeichert sein können. Das oberste Verzeichnis
heißt root Directory.
• In Linux gibt es gewöhnliche Dateien, Verzeichnisse (Directories) und spezielle Dateien
(Device Files). Je nach Aufgaben sind sie in Standardverzeichnissen abgespeichert.
• Datei und Verzeichnisnamen dürfen 254 Bytes lang sein, Groß- und Kleinbuchstaben
werden unterschieden, Wildcards (*,?,\,~) werden unterstützt.
• Zu jedem Zeitpunkt befindet sich der User in einem Working Directory, das er mit
pwd ausgeben und mit cd ändern kann.
• Datei- und Verzeichnisbezeichnungen können absolut (beginnend beim root Directory)
und relativ (beginnend beim Working Directory) angegeben werden.
• Der User kann Dateien anlegen (Befehl cat), am Terminal anzeigen (Befehl cat),
kopieren (Befehl cp), umbenennen (Befehl mv) und löschen (Befehl rm).
• Mehrere Dateien können nur in ein Verzeichnis kopiert werden. Verzeichnisse können
neu angelegt (Befehl mkdir) und falls falls sie leer sind, können Sie mit dem Befehl
rmdir, sonst mit dem Befehl rm -r gelöscht werden.
• Beim Kopieren und Umbenennen von Dateien verwaltet Linux keine alten Versionen
von Dateien, sondern überschreibt sie.
7.3. Editieren von Texten
105
7.2.6. Tipps für die Praxis
1. Gemeinsame Optionen -i, -r, -f bei Dateioperationen
Bei den Befehlen rm, cp und mv haben die Optionen -i, -r und -f die gleiche Funktionalität:
-i (interactive), fragt den Benutzer bevor eine Datei überschrieben wird.
-r (recursiv) Bei der Dateinamengenerierung werden auch Dateinamen aus den
Unterdirectories generiert.
-f (force) Keine Nachfragen.
2. Wildcard * und die Option -R beim ls Befehl
Wird ''ls *'' aufgerufen, so werden auch die Inhalte aller Unterverzeichnisse ausgegeben. ls -d * listet nur die Namen der Verzeichnisse auf.
Die Option -R listet den Inhalt und den Namen aller Verzeichnisse und Unterverzeichnisse auf.
3. More Befehl in Pipes
Erzeugt ein Befehl eine Terminalausgabe, die länger als eine Bildschirmseite ist, so
kann die Ausgabe, auf den less Befehl „gepiped“, also bildschirmweise ausgegeben
werden. ls * | less
4. Automatische Dateinamengenerierung bei Kommanodaufrufen.
Bei allen Kommandoaufrufen ist die automatische Dateinamengenerierung der Shell
eingeschaltet:
cd semin*
ist äquivalent zu cd seminar.
Die Kommandozeile kann auch durch die Tabulatortaste automatisch vervollständigt
werden.
cd sem <tab>
wird zu cd seminar, falls es nur ein Verzeichnis mit sem beginnend gibt,
anderenfalls erscheint nur ein Teilstück bzw. beim zweiten Drücken von <tab> eine
Auswahl.
5. Verhindern des automatischen Löschens oder Überschreibens von Dateien
Da Linux alte Versionen von Dateien defaultmäßig überschreibt, empfiehlt es sich für
die Befehl mv, cp und rm alias Definitionen mit der interactive Option einzuführen.
Die alias Definitionen werden mit der Option -f überschrieben.
alias
alias
alias
rm
cp
mv
rm -i
cp -i
mv -i
6. Wildcards bei Verborgenen Dateien
Wildcards in einem Dateinamen generieren keinen Dateinamen der mit einem Punkt
beginnt (=Verborgene Datei).
Abhilfe: ls .*
7.3. Editieren von Texten
7.3.1. Einleitung
Unter Linux gibt es mehrere Editoren mit verschiedenen Eigenschaften für unterschiedliche
Einsatzgebiete :
106
7. Linux
Beispiel 7.11
• vi:Fullscreen Editor, umschaltbar in den ex-Editor-Modus
• emacs: wichtiger GNU GPL Editor unter LINUX mit Arbeitsumgebung
• kate: ist ein freier Texteditor für Programmierer.
Diese drei Editoren haben verschiedene technische Bedingungen für die Nutzung. Der vi
läuft in jeder Konsole (Textmodus, xterm). Der emacs kann sowohl in der Konsole laufen
mit der Option -nw, als auch im grafischen Modus. Kate dagegen läuft nur im Grafikmodus,
genauer mit Hilfe von KDE-Bibliotheken auf X11 aufsetzend.
Ein weiteres Beispiel für einen simplen Editor in der Textkonsole ist mcedit. Gedit ist ein
weiterer Editor im Grafikmodus.
In diesem Kapitel lernen Sie:
• Aufrufen von kate
• Die Fenster von kate
• Die Menüeinträge von kate
• Erstellen einer neuen Datei
• Spezielle Kommandos zum praktischen Gebrauch
Aus dem Handbuch zu kate:
http://docs.kde.org/stable/de/kdesdk/kate/fundamentals.html#starting-kate
7.3.2. Aufrufen des kate Editors
kate wird vom K-Menü oder von der Befehlszeile aufgerufen.
Vom K-Menü
Das KDE → Programmmenü wird durch Klicken auf den großen K-Knopf oder das
jeweilige Symbol der Linux Version links unten auf dem Bildschirm in der Werkzeugleiste
geöffnet. Zeigen Sie mit der Maus auf den Menüpunkt Programme, Dienstprogramme,
Editoren. Es erscheint eine Liste der verfügbaren Editoren. Wählen Sie kate (auch aufgeführt
als erweiterter Texteditor). kate lädt die zuletzt bearbeiteten Dateien, außer Sie haben
eingestellt, dass dies nicht der Fall sein soll. Sehen Sie unter „Einstellungen - kate einrichten“
nach, wie Sie diese Funktion ein- und ausschalten können.
Von der Befehlszeile
Sie können kate auch von der Befehlszeile starten. Wenn Sie dabei gleichzeitig einen
Dateinamen angeben, wird diese Datei durch kate geöffnet oder erzeugt.
Verschiedene Modi von kate:
Textdatei
Mit Hilfe von kate kann man eine Textdatei erstellen indem man beim Speichern oder
Erstellen die Endung .txt hinzufügt.
7.3. Editieren von Texten
107
.perl Datei
Kate sieht eine Perldatei durch den Header #!/usr/bin/perl, um es übersichtlicher zu machen
fügt man beim Speichern noch die Endung .perl dazu.
7.3.2.1. Sitzungen:
Sitzungen erlauben Ihnen mehrere Listen von Dokumenten und Einstellungen für das
Benutzen in kate zu speichern. Sie können beliebig viele Sitzungen speichern, und Sie
können unbenannte oder anonyme Sitzungen für das einmalige Bearbeiten von Dokumenten
verwenden.
Neue Sitzung:
Wenn Sie eine neue Sitzung starten, dann wird das Dialogfenster für die Standardsitzung
geöffnet. Zum Speichern der Fenstereinstellungen in der Standardsitzung müssen Sie das Feld
„Fenstereinstellungen einbeziehen“ auf der Karte „Sitzungsverwaltung“ unter „Einstellungen
- kate einrichten“ einschalten, dann die Standardsitzung laden, die Fenstereinstellungen
anpassen und die Sitzung speichern.
Letzte Sitzung:
Wenn sie auf „Sitzung öffnen“ klicken so wird die alte von Ihnen verwendete Sitzung
geöffnet mit allen Fenstern, Verzeichnissen und Dateien mit denen schon gearbeitet wurde.
Im Editorbereich erscheint die letzte bearbeitete Datei.
Beispiel 7.12: Kate: Öffnen einer bestehenden Datei
kate Dateiname . txt
kate datei . perl
7.3.2.2. Erstellen einer neuen Datei
Es gibt 2 Möglichkeiten mit Hilfe von kate eine Datei zu erstellen:
1. In der Befehlszeile wird der Name einer neuen Datei angegeben:
kate neuedatei . perl
Die Datei wird im Verzeichnis Documents angelegt. Daher ist es empfehlenswert die
zweite Möglichkeit vorzuziehen um alle z.B. Perldateien in einem extra Verzeichnis
zur Verfügung zu haben.
2. Kate aufrufen:
kate
Datei → Neu
kate ünterstützt das Drag-and-Drop-Protokoll von KDE. Dateien können gezogen und auf
kate abgelegt werden; von der Arbeitsoberfläche, Dolphin, oder einer FTP-Seite, die in
einem Dolphin-Fenster geöffnet ist.
108
7. Linux
Abbildung 7.3.: Editor: Kate
7.3.2.3. Die Fenster des kate Editors
Kate ist in verschiedene Bereiche geteilt : Das Hauptfenster von kate ist ein StandardKDE-Anwendungsfenster mit einer zusätzlichen Seitenleiste, die Werkzeugansichten enthält.
Es hat eine Menüleiste mit den Standardmenüs und einigen mehr, sowie eine Werkzeugleiste
mit Knöpfen für oft benutzte Befehle.
Der wichtigste Teil des Fensters ist der Editorbereich, der standardmäßig einen Texteditor
anzeigt, in dem Sie Ihr Dokument bearbeiten können.
Die Dokumentenliste zeigt alle aktuell in Kate geöffneten Dateien an. Dateien, die noch
nicht gesicherte Änderungen enthalten, werden mit einem kleinen DiskettenSymbol links
neben dem Dateinamen gekennzeichnet.
Wenn zwei oder mehrere Dateien mit dem selben Namen (in verschiedenen Verzeichnissen)
geöffnet sind, wird an die Namen eine Zahl angehängt z. B. ”< 2 >” usw. Für die Auswahl
der gewünschten Datei wird ihr Name einschließlich Pfad in der Kurzinfo angezeigt.
Wenn Sie ein Dokument aus der Liste aktiv machen wollen, klicken Sie einfach auf den
Namen des Dokuments in der Liste.
Die Dokumentenliste stellt standardmäßig die Einträge farbig dar: Die Einträge der zuletzt
bearbeiteten Dokumente werden mit einer Hintergrundfarbe hervorgehoben, Dokumente,
die tatsächlich bearbeitet wurden, werden durch eine zusätzlich eingeblendete Farbe
hervorgehoben. Das Dokument, das zuletzt bearbeitet wurde, hat die stärkste Farbe, so
dass Sie die Dokumente, an denen Sie aktuell arbeiten, einfach finden können. Diese
Hervorhebungen können Sie im Einrichtungsdialog für die Dokumentliste einrichten.
Der Dateisystem-Browser ist ein Verzeichnisanzeiger, von dem aus Sie Dateien im
aktuell angezeigten Verzeichnis öffnen können.
Von oben nach unten besteht der Dateisystem-Browser aus folgenden Elementen:
Einer Werkzeugleiste, diese enthält Standardnavigationsknöpfe zum schnellen Wechsel der
Verzeichnisse.
Die Standardposition der Dokumentliste sowie vom Dateisystem-Browser ist links vom
Editorbereich im Kate-Fenster. Der eingebaute Terminal-Emulator ist eine Kopie der KDEAnwendung Konsole, er ist durch Wählen von Fenster → Werkzeugansichten → Terminal
7.3. Editieren von Texten
109
anzuzeigen oder einfach durch Drücken der Taste F7 aufrufbar und bekommt beim Einschalten den Fokus. Wenn die Option „Automatisch mit dem aktuellen Dokument abgleichen“
im Feld „Einstellungen“ von Kate einrichten eingeschaltet ist, wird das Verzeichnis des
Terminal-Emulators in das Herkunftsverzeichnis der aktuellen Datei umgeschaltet, wenn
dies möglich ist.
Die Standardposition ist unten im Kate-Fenster, unterhalb des Editorfensters.
7.3.3. Wichtige Menüeinträge
Das Menü Datei
• Datei → Neu (Strg+N)
Dieser Befehl startet eine neue Datei im Editorfenster. In der Dateiliste links wird
die neue Datei als „Unbenannt“ bezeichnet.
• Datei → Öffnen (Strg+O)
Öffnet das Standard-KDE Dialogfenster, das das Öffnen einer oder mehrerer Dateien
erlaubt.
• Datei → Zuletzt geöffnete Dateien
Dieser Befehl öffnet ein Untermenü mit einer Liste der zuletzt bearbeiteten Dateien.
Sie können daraus direkt eine dieser Dateien öffnen.
• Datei → Öffnen mit
Dieses Untermenü enthält eine Liste mit Anwendungen, die den MIME-Typ des
aktuellen Dokumentes verarbeiten können. Das Klicken auf einen Eintrag öffnet das
aktuelle Dokument mit dieser Anwendung.
Weiterhin gibt es einen Eintrag „Sonstige“. Dieser Befehl öffnet ein Dialogfenster, in
dem Sie eine andere Anwendung auswählen können, in der die aktive Datei geöffnet
werden soll. Die aktive Datei bleibt weiterhin in Kate geöffnet.
• Datei → Speichern (Strg+S)
Dieser Befehl speichert Ihre Datei. Benutzen Sie ihn oft. Solange die Datei noch
den Namen Unbenannt trägt, wird automatisch anstelle von Speichern der Befehl
„Speichern unter“ ausgeführt.
• Datei → Speichern unter
Mit diesem Befehl benennen Sie Dateien oder benennen diese um. Es wird das
Dialogfenster zum Speichern einer Datei aufgerufen. Dieses Dialogfenster funktioniert
genauso wie das Dialogfenster zum Öffnen einer Datei. Sie können sich durch das
Dateisystem bewegen, eine Vorschau von vorhandenen Dateien ansehen oder Masken
zur Dateiauswahl benutzen. Geben Sie den Namen, den Sie der Datei geben wollen,
in das Feld ein und klicken Sie auf OK. Achten Sie dabei auch auf die Kodierung.
Das Menü Bearbeiten
• Bearbeiten → Überschreibmodus (Einfg)
Schaltet zwischen den beiden Arten des Eingabemodus um. Wenn der Modus EINF
ist, dann setzen Sie die eingegebenen Zeichen an der Stelle des Cursors ein. Wenn der
Modus Überschr. ist, dann ersetzt jedes eingegebene Zeichen ein Zeichen rechts vom
Cursor. Die Statusleiste zeigt den aktuellen Status des Auswahlmodus an, entweder
EINF oder Überschr.
110
7. Linux
Das Menü Ansicht
• Ansicht → Zeilennummern anzeigen (F11)
Mit diesem Eintrag wird ein zusätzlicher Rand an der linken Seite des aktiven
Rahmens ein- oder ausgeschaltet, der Zeilennummern anzeigt.
Das Menü Extras
• Extras → Terminal mit aktuellem Dokument synchronisieren
Diese Option bewirkt, dass der eingebaute Terminal-Emulator immer mit cd zum
Ordner des aktuellen Dokuments wechselt, wenn ein neues Dokument geöffnet wird
oder zu einem anderen Dokument umgeschaltet wird.
• Extras → Kodierung
Sie können die Standardeinstellung für die Kodierung, die in Einstellungen → Kate
einrichten ... Öffnen/Speichern festgelegt ist, für dieses Dokument hier verändern.
• Extras → Kommentar
Dies fügt das Zeichen für eine Kommentarzeile und ein Leerzeichen an den Zeilenanfang der aktuellen Zeile oder der aktuellen Auswahl hinzu.
• Extras → Kommentar entfernen
Dies entfernt das Zeichen für eine Kommentarzeile und ein Leerzeichen (sofern
vorhanden) am Zeilenanfang der aktuellen Zeile oder der aktuellen Auswahl.
• Extras → Großschreibung
Der ausgewählte Text oder der Buchstabe nach dem Cursor wird in Großschreibung
gesetzt.
• Extras → Kleinschreibung
Der ausgewählte Text oder der Buchstabe nach dem Cursor wird in Kleinschreibung
gesetzt.
• Extras → Großschreibung am Wortanfang
Setzt den ausgewählten Text oder das aktuelle Wort in Großbuchstaben.
7.3.4. Spezielle Kommandos zum praktischen Gebrauch
Strg+Z Abbrechen und Rückgängigmachen eines kate Kommandos.
Strg+S Speichern der aktuellen Datei im aktuellen Zustand.
Strg+Q Beenden - Aktives Editorfenster schließen.
7.3.5. Andere Editoren
SED: Der sed ist ein batchorientierter Editor. Die Editor Kommandos werden in der
Aufrufzeile oder in Scriptfiles eingegeben. Der sed arbeitet die Befehle sequentiell ab und
schreibt das Ergebnis des Editierens auf das Terminal.
Aufruf :
sed [ - n ] -f scriptfile [ file - list ]
sed -n scriptfile [ file - list ]
7.4. Verwaltung von Dateien Teil 2
111
Beispiel 7.13: sed
sed s / abc / def / d
test
ersetzt den string abc durch den string def in jeder Zeile des Files test
sed -f script - file test
bearbeitet den File test mit den Kommandos aus script
GNU - EMACS: Er ist ein freier (GPL) fullscreen Editor, der für zahlreiche Linux
Systeme implementiert ist. Er bietet eine komplexe Arbeitsumgebung zum gleichzeitigen
Editieren, Programmerstellen und Arbeiten mit der Shell. Außerdem erlaubt er dem Benutzer, eine eigene Editorumgebung mit LISP ähnlichen Befehlmacros zu erstellen.
7.4. Verwaltung von Dateien Teil 2
7.4.1. Die einzelnen Merkmale einer Datei
7.4.1.1. Die Dateimerkmale im Überblick
Der Befehl ls -lisg listet alle Dateimerkmale :
Abbildung 7.4.: Dateimerkmale im Überblick
7.4.2. Gruppen und Owner
• Jedem Benutzer wird unter Linux in der Datei /etc/passwd eine eindeutige Benutzer(Benutzer ID) und eine Gruppennummer (Gruppen ID) zugeordnet.
Der UNIX Befehl id gibt die Benutzer und Gruppeneinstellungen an.
> id
• In einer Gruppe können mehrere Benutzer zusammengefasst werden.
• Unter Linux kann jeder Benutzer Mitglied mehrerer Gruppen sein.
• In der Datei /etc/group wird festgelegt, welcher Benutzer zu welcher Gruppe gehört.
Außerdem wird in dieser Datei für den Gruppen ID ein symbolischer Name definiert.
• Der Loginname ist der symbolische Name für den Benutzer ID.
• Benutzer IDs liegen zwischen 0 und 65535, wobei 0 für den Superuser reserviert ist.
Die Nummern 1-99 sind ebenfalls reserviert.
112
7. Linux
7.4.2.1. Zugriffsrechte unter Linux
Unter Linux werden folgende drei Klassen von Benutzern unterschieden :
u : user, gleicher User ID
g : group, gleicher Gruppen ID
o : beliebiger User - und Gruppen ID
Für jede dieser drei Benutzerklassen werden drei verschiedene Arten von Zugriff unterschieden :
r : Lesender Zugriff
w : Schreibender Zugriff
x : Ausführender Zugriff
Je nach Art der Datei haben die Zugriffsrechte verschiedene Bedeutungen :
Dateiart
Gerätedatei
Verzeichnis
normale Datei
read
darf vom Gerät
lesen
auf Dateien
darf zugegriffen
werden
lesen erlaubt
write
darf auf Gerät
schreiben
Dateien im
Verzeichnis
dürfen gelöscht
werden
ändern erlaubt
execute
––––
In das
Verzeichnis darf
mit cd gesprungen
werden
ausführen erlaubt
Tabelle 7.1.: Bedeutungen von Zugriffsrechten
Strategie zum Test der Zugriffsrechte bei Dateien
Abbildung 7.5.: Zugriffsrechte bei Dateien
Ändern der Zugriffsrechte
Die Zugriffsrechte einer Datei können mit symbolischen Werten oder mit einer Protectionmaske geändert werden.
Ändern mit symbolischen Werten :
chmod
chmod
chmod
chmod
u
g
o
a
<op >
<op >
<op >
<op >
rwx
rwx
rwx
rwx
dateiname
dateiname
dateiname
dateiname
oder
oder
oder
oder
Verzeichnisname
Verzeichnisname
Verzeichnisname
Verzeichnisname
u : user , g : group , o : other , a : all
7.4. Verwaltung von Dateien Teil 2
<op > ... =
<op > ... <op > ... +
113
explizites Setzen des angegebenen Rechts
wegnehmen des angegebenen Rechts
dazunehmen des angegebenen Rechts
Der Befehl lautet (ein Beispiel):
chmod a + r test
: alle erhalten das Recht zum Lesen
chmod ug + wx test
: User und Gruppe erhält das Recht zum Schreiben und Ausführen
Ändern mit einer Oktalzahl/Maske :
Der Befehl lautet:
chmod maske dateiname
user
r
w
x
0 1 0 1 0 1
4
2
1
erstes Byte
group
r
w
x
0 1 0 1 0 1
4
2
1
zweites Byte
other
r
w
x
0 1 0 1 0 1
4
2
1
drittes Byte
Tabelle 7.2.: Ändern mit einer Oktalzahl/Maske
Ein gesetztes Bit bedeutet, dass das Recht für die spezifische Gruppe gesetzt ist.
Beispiel 7.14
Es sollen folgende Rechte vergeben werden :
user = rw, group = x, other = daraus errechnet sich folgende Maske:
user = rw
group = x
other = -
. . . 110
. . . 001
. . . 000
→4·1+2·1+1·0=6
→4·0+2·0+1·1=1
→4·0+2·0+1·0=0
Maske = 610
Der Befehl lautet (ein Beispiel) :
> chmod 610 test
Einstellen der Defaultmaske
Wird eine Datei kreiert, so wird ihr Zugriffschutz nach einem Defaultwert festgelegt. Der
Defaultwert kann mit dem Befehl umask gesetzt werden.
Ändern der Gruppenzugehörigkeit einer Datei
Der Besitzer einer Datei kann, falls er Mitglied dieser Gruppe ist, die Gruppenzugehörigkeit
einer Datei ändern.
Der Befehl lautet (ein Beispiel):
> chgrp student2 test
Ändern des Owners einer Datei
Nur der Superuser kann den Owner einer Datei ändern.
Der Befehl lautet (ein Beispiel) :
> chown student test
114
7. Linux
7.4.3. Die Bedeutung von Devicegrenzen
7.4.3.1. Plattenplatzbelegung
Jede Plattenpartition entspricht im System einem Device.
Damit der Benutzer mit einem Device über eine Dateistruktur arbeiten kann, muss die
Partition initialisiert werden, wodurch die Partition als Dateisystem ansprechbar wird.
Ein Benutzer kann erst dann mit einem Dateisystem arbeiten, wenn es mit dem mount
Befehl in das hierarchische Dateisystem von Linux eingebunden ist. Beim mount Befehl muss
der Benutzer das Verzeichnis angeben, in das er das Dateisystem einbindet.
Der Befehl lautet (ein Beispiel) :
> mount / dev / sdc1 / usr
Nachdem das Dateisystem „gemounted“ ist, sind seine Dateien über die hierarchische
Dateistruktur zugänglich. Mit dem Befehl cd kann der Benutzer in jedes Verzeichnis
springen.
Der Befehl df gibt an, welche Dateisysteme in welches Verzeichnis gemounted sind :
> df
Filesystem
node
/ dev / sda1
/ dev / sdb1
/ dev / sdc1
Total
kbytes
15343
191958
49279
kbytes
used
9765
163585
35474
kbytes
free
4044
9178
8878
%
used
71%
95%
80%
Mounted on
/
/ usr
/ usr / users
7.4.3.2. Der Symbolic Link
Unter Linux kann man mit einem Dateinamen auf eine Datei zeigen, die auf einem anderen
Device liegt.
Die Verbindung zwischen Dateien über die Devicegrenzen hinweg funktioniert nur mit
einem symbolic link, innerhalb eines Devices sind auch hard links möglich.
Bei einem symbolic link wird im Header der Datei nicht die Inode - Nummer der Datei auf
die er zeigt, sondern der komplette Dateinamen, zusammen mit seinem Pfad eingetragen.
Der Referenzzähler erhöht sich bei symbolic links nicht.
Beispiel 7.15
Die Datei benutzer soll auf das Verzeichnis /usr/users zeigen. Die Datei benutzer darf
vorher nicht existieren :
> ln -s / usr / users benutzer
> ls -l benutzer
lrwxr - xr - x 1 kurs
5 Jul
4 15:30 benutzer -> / usr / users
7.4.4. Das Wichtigste in Kürze
• Die wichtigsten Dateimerkmale einer Datei sind:
Datei Eigentümer und - Gruppe
Dateischutz und andere Dateistatistik
Größe der Datei in Bytes
Blockadresse der Daten der Datei auf der Platte
Zeit der Datei - Erzeugung
Zeit des letzten lesenden Zugriffs
7.5. UNIX-Befehle
115
Zeit des letzten schreibenden Zugriffs
Anzahl der Verweise auf die Datei
• Jedem Benutzer unter Linux wird über seinen Benutzernamen ein Benutzer ID und
ein Gruppen ID zugeordnet.
• Der Benutzer root (Benutzer ID = 0) hat im Linux - System privilegierte Rechte und
kann alle Datei- und Systemattribute ändern.
• Ein Benutzer kann Mitglied mehrerer Gruppen sein.
• Jede Datei gehört einem Benutzer. Über Zugriffsrechte wird geregelt, für was eine
Datei verwendet werden kann.
• Bei den Zugriffsrechten werden drei Klassen unterschieden : user, group und other.
• Für jede Klasse kann man einen read, write oder execute Zugriff festlegen.
• Beim Bearbeiten einer Datei prüft Linux zu welcher Klasse der Benutzer, relativ vom
Besitzer der Datei gehört:
user : gleicher Benutzer ID
group : gleicher Gruppen ID
other : beliebiger Benutzer oder Gruppen ID.
• Die Zugriffsrechte unter Linux können symbolisch oder mit Oktalzahl gesetzt oder
geändert werden.
• Ein Datenträger wird unter Linux in Partitionen unterteilt, die, falls sie initialisiert
sind, ein eigenständiges Dateisystem haben.
• Dateisysteme werden in die hierarchische Dateistruktur von Linux eingebunden
(gemounted)
7.5. UNIX-Befehle
7.5.1. Hilfe (Befehlsoptionen, Parameter, generelle Verwendungsweise,
Verwendungsbeispiele)
• man Befehl
• info Befehl
Aufbau von man und info pages (Auszug):
– NAME (Names des Programms)
– SYNOPSIS (generelle Struktur des Befehls)
– DESCRIPTION (kurze Zusammenfassung, was der Befehl tut)
– OPTIONS (Optionen, Parameter und deren Beschreibung)
– EXAMPLES (Beispiele zur Verwendung, empfehlenswert!)
– SEE ALSO (man pages von ähnlichen Programmen oder config files)
• -h oder --help
Meist stehen auf beiden Seiten die gleichen Informationen, aber z.B. bei GNU Programmen
wird man in den Info Pages eher fündig (manchmal auch umgekehrt).
116
7. Linux
7.5.2. Einsatz der UNIX-Shell: Pipes, >, < (Ausgabeumleitung)
> sort liste > sortierte_liste
Hier wird die Ausgabe von sort in eine Datei umgeleitet.
> ls -l | less
Umleitung der Ausgabe von ls in das Programm less. Mehrfachverkettungen mittels Pipe
sind auch möglich s.u.
> cat File
Schreibt ein File in die Standardausgabe (meist das aktuelle Terminal), von der aus es
weiterverarbeitet werden kann.
> echo String
Zeigt den String in STDOUT an
> echo $Var
Zeigt den Inhalt der Variable Var in STDOUT an
> tail -n
Zeigt die letzten n Zeilen der Datei an.
> head -n
Zeigt die ersten n Zeilen der Datei an.
7.5.3. Kommandooptionen
Welche Kommandooptionen:
cmd -- help
-s value
# kurze Variante
-- size = value # lange Variante
7.5.4. Shells: bash, tcsh
piping |
redirecting > >> < << &1 &2
Control zur Steuerung von Prozessen:
^C
^S
^Q
^Z
Abbruch
Anhalten der Ausgabe aufs Terminal
resume der Ausgabe aufs Terminal
schicke Prozess in den Hintergrund :
neue Befehle z . B . bg oder fg damit er weiter läuft ,
können eingegeben werden
7.5.5. Was ist los auf dem Rechner?
> top
> ps
listet eigene Prozesse auf
> ps - ef
listet alle Prozesse am System auf
> ps - ef | grep bzip
7.5. UNIX-Befehle
117
listet alle Prozesse mit dem Namen bzip auf
> kill -9 PID
( Prozess Identification )
Wichtig ist die LOAD des Rechners. Etwas im Hintergrund arbeiten lassen: Am Ende des
Befehls ein & Zeichen: bzip wiki.dump &
7.5.6. Wegwerfen der Ausgabe einer Datei
> / dev / null
Metazeichen der SHELL um Dinge zu demaskieren:
' (umklammern mit Hochkomma )
\ (Backslash vor einzelnen Sonderzeichen
Beispiele:
\<ret> Verlängerungszeichen einer Zeile
\<space> Leerzeichen in Dateinamen
7.5.7. Archive anlegen
Behält die Direktory Struktur, Zeit, Owner und die Zugriffsrechte
tar - cf archiv . tar file1 file2 file2 ...
oder
tar - cf archiv . tar dir1 dir2 ?
7.5.8. Komprimieren von Dateien
zip - unzip
gzip - gunzip
gunzip -c ( zcat )
bzip2 - bunzip2
bzcat
7z
. zip
. gz
. bz2
.7 z
7.5.9. Archivieren mit Komprimieren
tar - zcvf archiv . tgz file1 file2 file2 ...
oder
tar - zcvf archiv . tgz dir1 dir2 ...
Entpacken:
tar - zxvf archiv . tgz
Auflisten des Inhalts eines Archivs
tar - tf archiv . tar
7.5.10. Finden von Dateien und ausführen eines Befehls
find
zum Extrahieren aller Files eines Verzeichnisbaums und Anwenden eines Befehls
> find . - name "*. txt " - print
> find . - name "*. txt " - exec bzcat '{} ' \;
| lynx - stdin - dump - display_charset = utf8
> find . - name "*. txt " | xargs bzcat
118
7. Linux
7.5.11. Finden von Unterschieden in Dateien
> cmp
Vergleicht zwei Dateien Byte für Byte
> diff
Vergleicht zwei Dateien Zeile für Zeile
> diff3
Vergleicht zwei Dateien Byte für Byte
7.5.12. UNIX: Tokenisierung, Sortieren, Frequenzlisten
Tokenisierung
• tr
• grep -o
• egrep -o
• perl
7.5.13. Translate von Zeichen
Achtung: bisher (Stand 2010) bietet UNIX beim Befehl tr keine utf8 Unterstützung.
> tr -d a < sz . txt
löscht alle „a“ aus dem Text
> tr -d a < sz . txt
löscht alle „a“ aus dem Text
> tr " " "\ n "
löscht alle Spaces und ersetzt sie mit einem Newline
> tr -C -d [a - m ] < sz . txt
> tr [a - z ] [A - Z ] < sz . txt
> tr -s " " "\ n "
< sz . txt
ersetzt alle wiederholten spaces aus dem Text
7.5.14. Sortieren-einer-wortliste
UNIX Befehl sort
• lexikalisch (sort ohne parameter)
• nummerisch (sort -n)
• aufsteigend (ohne Parameter). absteigend (sort -r)
• nach Feldern
> tr -s " " "\ n " < sz . txt | sort -f # ignoriert Groß / Kleinschreibung
> sort -n # numeric sort
> sort -f -S 20 M sz_utf8 . txt
# mit großem Buffer
### SIZE may be followed by the following multiplicative suffixes : % 1%
### of memory , b 1 , K 1024 ( default ) , and so on for M , G , T , P , E , Z , Y
7.5. UNIX-Befehle
119
7.5.15. Report und Unterdrücken von Zeilen
> uniq -c
report or omit repeated lines
> uniq -c
zählt die Wiederholungszeilen und schreibt die Anzahl davor
> sort -n
numerischer sort
> sort - rn
numerischer reverse sort
> sort -k 2
> sort -- key =2
sortieren nach Keys (Feld, welches als Sortierschlüssel dient; wenn nicht angegeben wird
gesamte Zeile verwendet)
7.5.16. Erzeugen einer Wortliste
> tr -s " " "\ n " < sz_txt . txt | sort | uniq -c | sort - nr | less
oder :
> cat sz_txt . txt | tr " " "\ n "| sort -f | uniq - ic | sort -n > ausgabedatei
Die Befehle einzeln:
> cat
sz_txt . txt
Schreibt die Datei nach STDOUT (Standardausgabe), dort wird sie von der Pipe weitergeleitet.
> tr " " "\ n "
Übersetzt Leerzeichen in newlines.
> sort -f
Ignoriert Groß- und Kleinschreibung für die Sortierung.
> uniq - ic
-c
zählt die einzelnen Tokenvorkommen. -i zählt groß- und kleingeschriebene Vorkommen
zusammen.
> sort -n
Sortiert nummerisch (nach dem Ergebnis von uniq)
> ausgabedatei
Leitet in Ausgabedatei um.
174
153
125
118
100
84
57
56
54
49
49
48
46
die
der
und
Linux
von
zu
in
für
mit
den
auch
eine
120
7. Linux
? usw ..
13 werden .
13 über
(...)
Bei diesem Ergebnis handelt es sich um eine einfache Frequenzliste, die noch nicht um
newlines, Kommata, Anführungszeichen, etc. bereinigt wurde. Dazu empfiehlt es sich, ein
Tool zur Behandlung regulärer Ausdrücke zu verwenden (s.u.).
7.6. Automatisieren von Befehlsfolgen mit der Shell
7.6.1. Was ist ein Shellscript
Eine Datei, die Shell Kommandos enthält, nennt man Shell Script.
In einem Shellscript kann man Linux Befehle, eigene Programme oder andere Shellscripts
aufrufen.
Über Ablaufsteuerungsanweisungen, Abfragen und Ausgaben an den Benutzer und den
Einsatz von Variablen kann man die Reihenfolge und den Inhalt der aufgerufenen Befehle
steuern.
Ein Shellscript wird für eine bestimmte Shell konzipiert (Bourne Shellscript, C-Shellscript,
Korn-Shellscript), da sich danach Befehle und Mechanismen richten, die verwendet werden
können.
Alle Linux System Shellscripts sind Bourne Shellscripts.
Ein Shellscript wird mit dem Namen gestartet und von einer bestimmten Shell sequentiell
interpretiert.
7.6.2. Benutzung von Shellscripts
• komplizierte, sich öfter wiederholende Befehlsfolgen können vereinfacht und so automatisiert werden (Programmerstellung)
• für Systemaufgaben, wie login-Vorgang, Backup, Hochfahren des Systems.
• Die zahlreichen Testmöglichkeiten unter Linux einzusetzen damit bei Kommandofolgen keine Fehler passieren.
• Für Anfänger erleichtern Scripts komplizierte Befehle.
7.6.3. Das Wichtigste in Kürze
• Shellscripts sind in einer Datei zusammengefasste Befehle für eine spezifische Shell
• Es gibt verschiedene Shellscripts
• In Shellscripts kann man Kommentare eintragen, Variablen einsetzen, vom Benutzer
Eingaben fordern, Text ausgeben, und mit Kontrollstrukturen arbeiten.
• Die System Shellscripts sind für die Bourne Shell geschrieben.
• Für die Bourne Shell gibt es folgende Kontrollstrukturen:
if then φ
if then else φ
if then elif φ
for in do done
7.7. Drucken
121
while do done
until do done
case in esac
7.7. Drucken
7.7.1. CUPS
CUPS, auch für Common Linux Printing System - heute oft das Standarddrucksystem. Die
folgenden Befehle sind eher historisch, aus Kompatibilitätsgründen aber in jedem System
vorhanden.
7.7.1.1. Druckaufträge erzeugen (klassisch)
lpr text . txt
7.7.1.2. Das Anzeigen von Druckjobs
Zum Ausgeben von Information über den aktuellen Zustand der Drucker, die an das System
angeschlossen sind und über den Zustand des Druckauftrags gibt es den Befehl:
lpstat
Falls ein eigener Druckjob gestartet ist.
bzw.
lpstat -t
was die gesamte Information über alle Queues und Drucker am System ausgibt. lpq ist eine
weitere Möglichkeit der Abrage.
Zur Verwaltung von Druckern gibt es ein spezielles Drucker-Kontroll-Programm lpc. Es
erlaubt den Druckerstatus auszugeben und zu ändern.
7.7.1.3. Das Löschen von Druckjobs
Jeder Benutzer kann seinen eigenen, der Superuser beliebige Druckaufträge über die
Auftragsnummer stoppen :
lprm auftragsnummer
7.7.1.4. Das Wichtigste in Kürze
Drucker werden über spezielle Programme, sogenannte Druckerdämons verwaltet.
Die Aufgabe des Druckerdämons ist, nur einen Druckauftrag an einem Drucker zu
einem Zeitpunkt zuzulassen.
Der Systemverwalter definiert für jeden Drucker eine Warteschlange.
Der Benutzer wählt beim Druckbefehl die Warteschlange und somit den Drucker.
Nachdem der Benutzer den Druckbefehl abgeschickt hat, wird die zu druckende Datei
mit den Druckinformationen in das systemweite spool-Verzeichnis kopiert und wenn
der Drucker frei ist, vom Druckerdämon zum Drucker geschickt.
Information über den Drucker und die Druckaufträge bekommt man mit dem Befehl
lpstat -t.
122
7. Linux
Jeder Benutzer kann seinen Auftrag über die Auftragsnummer mit dem Befehl lprm
löschen.
Des Printer-Kontroll-Programm lpc erlaubt Drucker anzuhalten und neuzustarten.
7.8. Linux-Befehle – eine kurze Übersicht
7.8.1. Dokumentation, Dateien, Pfade
Befehl
wichtige
Optionen
Beispiel
Beschreibung
man,
info,
whatis,
apropos
cd
man ls, info ls
Hilfe zu einem Befehl (manual)
cd /tmp
pwd
pwd
wechselt in das genannte Verzeichnis
(change directory)
pwd gibt das aktuelle Verzeichnis aus
(print working directory)
gibt den Inhalt eines Verzeichnisses
(bei -R auch Unterverzeichnisse) aus
(list); -l: langes Format, -a: auch
versteckte Dateien
kopiert Dateien (copy); -R mit Unterverzeichnissen; -a Archiv-Modus (u.a.
Unterverzeichnisse samt Inhalt mit
kopieren); -i Interaktive Mode, fragt
nach vor eventuellem Überschreiben
verschiebt Dateien oder benennt um
(move); -i (interactive): vor dem Überschreiben von Dateien rückfragen
legt datei an
löscht Dateien (remove); -f(force)
Löschen erzwingen; -r (rekursiv):
Verzeichnis samt Inhalt löschen
(gefährlich!)
Verzeichnis anlegen (make directory);
-p (parents): Verzeichnisbaum anlegen
Verzeichnis löschen (remove direcotry);
-p (parents): Verzeichnisbaum löschen,
wenn leer
harten Link anlegen; -s: symbolischen
Link anlegen
Lese-(r), Schreib-(w) und Ausführrecht
(x) für Besitzer (u), Gruppe (g), Rest
der Welt (o) und/oder alle (a) hinzufügen(+), wegnehmen (-) oder exakt
setzen (=)
Ändert die Gruppenzugehörigkeit
einer Datei; im Beispiel wird datei der
Gruppe users zugeordnet.
Ändert die Eigentümer einer Datei; im
Beispiel wird datei dem Benutzer root
zugeordnet
zeigt ACL-Zugriffsrechte von datei an
ls
-l -a -R
ls -l /tmp
cp
-a -R -i
cp quelle ziel
mv
-i
mv quelle ziel
touch
rm
-f -r
touch datei
rm datei
mkdir
-p
rmdir
-p
mkdir -p newdir/
newsub
rmdir verzeichnis
ln
-s
ln -s original link
chmod
[ugoa][+=][rwx]
chmod go-rwx datei
chgrp
chgrp users datei
chown
chown root datei
getfacl
getfacl datei
7.8. Linux-Befehle – eine kurze Übersicht
setfacl
-m -x
setfacl -m u:user:r datei
getfattr
setfattr
getfattr -d -m ’-’ datei
setfattr datei
123
setzt ACL-Zugriffsrechte von datei; im
Beispiel wird dem Login user Leserechte(r) auf datei gegeben; -m: Rechte
setzen; -x: Rechte löschen
zeigt erweiterte Attribute von datei an
setzt erweiterte Attribute von datei
Tabelle 7.3.: Linux-Befehle: Dokumentation, Dateien, Pfade
7.8.2. Textverarbeitung
Befehl
Beispiel
Beschreibung
cat
wichtige
Optionen
-n
cat datei
head, tail
-n
head -n 100 datei
wc
-c -m -l -w
wc -l datei
more, less
-S
less -S datei
sort
-r -n
sort datei
grep
-i -l -v -r
grep -i regexp datei(en)
agrep
-Abstand
agrep -2 ”hallo” datei
Dateiinhalt ausgeben (concatenate);
-n Zeilen numerieren
gibt die ersten/letzten 100 Zeilen von
datei aus. tail -f fortlaufend
gibt die Anzahl der Bytes (-c), Zeichen
(-m), Zeilen (-l) oder Wörter (-w) von
datei aus.
zeigt eine Datei seitenweise an;
-S: Zeilen nicht umbrechen (nur less)
sortiert eine Datei; -r: rückwärts
sortieren; n numerisch sortieren
durchsucht datei(en) nach einem
regulären Ausdruck und gibt passende Zeilen aus; -i (ignore case) Groß/Kleinschreibung ignorieren, -l (list):
lediglich Dateien mit Treffern anzeigen;
-v: (invert match): nur nicht-passende
Zeilen ausgeben; -r: alle Dateien unter einem Verzeichnis rekursiv durchsuchen
Findet ”hallo” oder ähnliche Schreibweisen in datei. Über -Abstand wird
der Levenshtein-Abstand eingestellt.
Zeichen ersetzen. Im Beispiel wird
jedes ”a”, das von stdin gelesen wird,
durch ”b” ersetzt.
ersetzt regulären Ausdruck durch
Replacement
Löscht alle doppelten Zeilen in datei1
und schreibt das Ergebnis nach datei2 ;
-c: Anzahl der Vorkommen angeben
vergleicht 2 Dateien (difference);
-r: Verzeichnisse rekursiv vergleichen
extrahiert spaltenweise Ausschnitte aus Textzeilen; -d: Angabe der
Trennzeichen; -f: Angabe der zu
extrahierenden Felder
verknüpft Zeilen mit identischen
Feldern; -e: ersetzt fehlende Felder
durch festgelegte Zeichenkette
tr
tr ”a” ”b”
sed
s
sed s/regexp/replace/
uniq
-c
uniq -c datei1 datei2
diff
-r -y
diff alt neu
cut
-d -f
cut -d “,“ -f1 datei
join
-e
join first last
Tabelle 7.4.: Linux-Befehle: Textverarbeitung
124
7. Linux
7.8.3. Komprimieren von Dateien/ Ordnern
Befehl
wichtige
Optionen
[t|x|c][j|z]f
Beispiel
Beschreibung
tar xvjf datei.tar.bz2
gunzip, gzip,
zcat
-l
gunzip -l datei.gz
unzip, zip
-l
unzip datei.zip
bzip2
7za
x
bzip2 datei
7za x datei.7z
split
-b=650m
split -b=650m datei
.tar.bz2-Archiv
anzeigen
(test),
auspacken (extract) oder anlegen
(create) (tape archiver). z bei gzipkomprimierten Dateien (.tgz oder
.tar.gz), j bei bzip2-komprimierten
Dateien (.tbz oder .tar.bz2)
.gz-Datei auspacken oder Inhalt
auflisten (-l); gzip: Datei packen; zcat
Datei packen und auf stdout schreiben
.zip-Datei auspacken oder Inhalt
auflisten (-l); zip: zip-Datei packen
Packt datei nach datei.bz2
Entpackt Dateien aus dem Archiv
datei.7z
Teilt datei in mehrere 650 MB große
Stücke, zusammensetzen mit cat
tar
Tabelle 7.5.: Linux-Befehle: Komprimieren
7.8.4. Dateisystem
Befehl
wichtige
Optionen
Beispiel
Beschreibung
locate
locate *.pl
find
find -name ”foo*”
mount/umount
mount
/dev/sdb1
/mnt/sdb1
gvfs-mount
-d
/dev/sdb1
Dateien lokalisieren (benötigt regelmäßige Läufe von updatedb), hier werden
alle Dateien mit Endung .pl angezeigt
aktuelles Verzeichnis und Unterverzeichnisse nach Dateien durchsuchen,
deren Name auf ein Muster passt
Laufwerk einbinden/aushängen (mit
Root-Rechten)
bindet Laufwerke mittels Gnome
Virtual File System (GVFS) ein (ohne
Root-Rechte)
zeigt den durch die Dateien eines Verzeichnisses und seine Unterverzeichnisse belegten Platz an (disk usage);
-s (summary): lediglich Gesamtwert,
nicht jedes einzelne Unterverzeichnis
ausgeben; -h: sinnvolle Größenangabe
Zeigt die Belegung der gemounteten
Laufwerke an; -h: sinnvolle Größenangabe
gvfs-mount
du
-s -h
du -s ./
df
-h
df -h
Tabelle 7.6.: Linux-Befehle: Dateisystem
7.8. Linux-Befehle – eine kurze Übersicht
125
7.8.5. Prozessmanagement und User
Befehl
su
wichtige
Optionen
-
sudo
Beispiel
Beschreibung
su - kennung
Shell mit anderer Benutzerkennung
starten (root, wenn kein Benutzer
genannt ist); -: Login-Shell starten
Program mit root-Rechten ausführen
(super user do)
Prozessliste anzeigen (processes), zeigt
PIDs zu Prozessen an
Signal an den Prozess mit der ProzessID PID schicken, Standard: SIGTERM (termination); -9: SIGKILLSignal schicken
Prozess über seinen Namen beenden
Startet befehl mit Priorität 10. Je kleiner die Zahl desto größer die Priorität,
0 normale, -20 höchste, 19 niedrigste
Priorität.
Setzt für PID die Priorität prio, prio
∈ [-19,20]
zeigt eine selbstaktualisierende Tabelle mit Prozessinformationen an(q für
quit)
setzt den Prozess %1 fort (%1 ist
die Nummer des Prozesses, der mit
Strg+Z unterbrochen wurde)
Benutzer anzeigen, die zuletzt auf diesem Rechner waren.
anzeigen wer eingeloggt ist (who).
w zeigt zusätzlich Informationen über
laufende Prozesse an, finger zeigt Kontaktinformationen über einen Benutzer an
sudo /sbin/halt
ps
aux
ps aux
kill
-9 -l
kill PID
killall
nice
-9
-n
killall find
nice -n 10 befehl
renice
renice prio PID
top
top
bg, fg
bg %1
last
who, w, finger
-a -i
last -a -i
finger login
Tabelle 7.7.: Linux-Befehle: Prozessmanagement und User
126
7. Linux
7.8.6. Zeichensätze
Befehl
Beispiel
Beschreibung
recode
wichtige
Optionen
-l
recode latin-1..utf-8
iconv
-l -f -t
uniconv
-decode encode -l
iconv -f l1 -t utf8
text.txt
uniconv -decode utf-8 encode German
locale
-a
locale
file
-i
file datei.txt
Konvertiert eine Datei zwischen
verschiedenen Speicherformaten
Konvertiert eine Datei zwischen
verschiedenen Speicherformaten
Liest Zeichen von stdin und schreibt
nach Beendigung der Eingabe die Zeichen auf stdout wobei die Umlaute durch ihre Umschreibung ersetzt
wurden.
zeigt
landesspezifische
Umgebungsvariablen an
Dateityp erraten; -i: Mime Typ
ausgeben
zeigt Daten byteweise in oktaler oder
hexadezimaler Form an
hexdump, od
hexdump -C UTF-8demo.utf | less
Tabelle 7.8.: Linux-Befehle: Zeichensätze
7.8.7. Umgebungsvariablen
Befehl
wichtige
Optionen
export
set
unset
setenv
echo
Beispiel
export
LANG
”de_DE@euro”
-n
echo ”$PATH”
Beschreibung
=
setzt Variablen, zeigt ohne Argumente
alle Umgebungsvariablen an
zeigt Umgebungsvariablen an
löscht Umgebungsvariable
wie export für andere Shells
Variable ausgeben; -n (newline): kein
Zeilenvorschub nach Ausgabe
Tabelle 7.9.: Linux-Befehle: Umgebungsvariablen
7.8.8. Netzwerkeigenschaften
Befehl
ss
ping
ip address
ip -6 route
wichtige
Optionen
-p
Beispiel
Beschreibung
ss -p
zeigt Informationen über das Netzwerk an; -p: Anzeige der dazugehörigen
Prozesse
Server anpingen (ohne Option -c mit
ctrl+c abbrechen)
Anzeige der IP Adresse
Anzeige der IP-Routen (-6 für IPv6Routen)
ping6 www.lrz.de
Tabelle 7.10.: Linux-Befehle: Netzwerkeigenschaften
7.8. Linux-Befehle – eine kurze Übersicht
127
7.8.9. Via Internet Dateien kopieren/ Rechner fernsteuern
Befehl
wget
wichtige
Optionen
-p -r -l
curl
-O
ssh
-X
scp
rsync
-a –delete
-n
sftp
rdesktop
vncviewer
Beispiel
Beschreibung
wget
-p
http://www.lmu.de
Internetseite auf Festplatte kopieren;
-p: alle zur Darstellung der Seite
relevanten
Dateien
mitladen;
-r:
Seite
rekursiv
laden;
-l: Rekursionstiefe begrenzen
curl http://www.lmu.de Internetseite auf Terminal anzeigen;
-O: schreibt Output in Datei
ssh -X login@ssh.cip. ssh-Verbindung zu Server aufbauen
ifi.lmu.de
scp
login@ssh.cip. Kopiert die Datei datei von der Uni
ifi.lmu.de:datei ziel
an die Stelle ziel
rsync
rsync
-av
LocalDir/
user@host.domain.tld:/RemoteDir/
sftp login@sftp.home. sftp-Verbindung zu Server aufbauen
lan
rdesktop
-g
80% baut Remote-Desktop-Verbindung auf
remote.cip.ifi.lmu.de
vncviewer
Zugriff auf entfernten Rechner/
vnc.cis.lmu.de:1
Virtual Network Computing
Tabelle 7.11.: Linux-Befehle: Rechner fernsteuern
7.8.10. Operatoren zur Ausgabe-/Eingabeumleitung
Befehl
wichtige
Optionen
<
>
2>
»
|
``
Beispiel
Beschreibung
tr -s “a“ < datei
ls > datei.txt
befehl 2>&1
ls » datei.txt
cat sz.txt | less
stdin umleiten
stdout umleiten
stderr umleiten
stdout an Datei anhängen
an Prozess weiterleiten
mit Ergebnis des Programmaufrufs
weiterarbeiten (`Befehl`)
liest von stdin und schreibt zu stdout
und Dateien
tee
Tabelle 7.12.: Linux-Befehle: Operatoren
7.8.11. Versionsverwaltung
Befehl
svn
git
wichtige
Optionen
co ci add
up
Beispiel
Beschreibung
svn co
add push
pull
git pull
Dateien mittels svn runterladen
(co,up), hochladen (ci) oder zum
Repository hinzufügen (add).
Dateien mittels git runterladen (pull),
hochladen (push) oder zum Repository
hinzufügen (add).
Tabelle 7.13.: Linux-Befehle: Versionsverwaltung
128
7. Linux
7.8.12. Sonstiges
Befehl
screen
wichtige
Optionen
-r
lpr, lprm, lpq
crontab
Beispiel
Beschreibung
screen befehl; screen
-v
parkt aktive Sessions, wichtige Tastenkombination: ctrl+A, D, C, A
lpr druckt datei auf einem Drucker;
lprm löscht Druckjobs, lpq zeigt Druckjobs an
Crontab bearbeiten (-e), anzeigen (-l),
oder löschen (-r)
Befehl zu bestimmten Zeitpunkt
ausführen
Terminal wiederherstellen
brennt iso.images
-o
erzeugt CD/DVD image-Datei
lpr datei
-e -l -r
crontab -e
at, atrm, atq
echo ”reboot” | at 5:00
clear, reset
cdrecord, wodim
reset
wodim
dev=/dev/dvd
image.iso
genisoimage
image.iso pfad
which rm
mkisofs, genisoimage
which
-J -r -o
kompletten Pfad eines Programmes in
$PATH ausgeben
Tabelle 7.14.: Linux-Befehle: Sonstiges
Literaturverzeichnis
[H.-94] H.-P. Gumm, M. Sommer: Einführung in die Informatik, Addison-Wesley, Bonn. 579 S.,
359 Abb., Hardcover (1994) (Zitiert auf Seite 1)
[Kla90] Klaeren, Herbert: Vom Problem zum Programm (1990) (Zitiert auf Seite 1)
[LW00] Larry Wall, Jon Orwant, Tom Christiansen: Programming Perl, Third Edition, O’Reilly
Media (2000) (Zitiert auf Seiten 11 and 12)
[TP01] Tom Phoenix, Randal L. Schwartz: Learning Perl, Third Edition, O’Reilly Media (2001)
(Zitiert auf Seite 12)
129
Abbildungsverzeichnis
2.1. Editor:Kate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
7.1.
7.2.
7.3.
7.4.
7.5.
Graphische Darstellung des LINUX-Systems
Hierarchische Dateistruktur von LINUX . .
Editor: Kate . . . . . . . . . . . . . . . . . .
Dateimerkmale im Überblick . . . . . . . .
Zugriffsrechte bei Dateien . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
98
100
108
111
112
A.1.
A.2.
A.3.
A.4.
A.5.
A.6.
compond-statement .
expression-statement
if-statement . . . . .
while-statement . . .
for-statement . . . .
do-statement . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
132
133
133
133
133
134
130
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Tabellenverzeichnis
1.1. Die Rechnergenerationen bis ca. 1990 im Überblick . . . . . . . . . . . . . . . . . .
2.1. Elemente in einer Liste . . . . . . . . . . . . . . . . .
2.2. Logische Operatoren . . . . . . . . . . . . . . . . . .
2.3. Logische Aussagen . . . . . . . . . . . . . . . . . . .
2.4. Vergleichsoperatoren . . . . . . . . . . . . . . . . . .
2.5. Wahre Werte in einem logischen Ausdruck . . . . . .
2.6. Falsche Werte in einem logischen Ausdruck . . . . .
2.7. Zeichencodierung: ASCII, für Buchstaben, mit 7 Bit
2.8. Bedeutung der Steuerzeichen . . . . . . . . . . . . .
2.9. Definitionen des ISO-Latin-1 Character Set . . . . .
2.10. ISO Codierung . . . . . . . . . . . . . . . . . . . . .
2.11. UNICODE Codierung . . . . . . . . . . . . . . . . .
2.12. Die UTF Kodierung im Detail . . . . . . . . . . . . .
2.13. Hash: Zugriff und sort Anweisungen . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
16
24
24
25
26
26
39
40
42
43
43
45
55
3.1. Buchstabenklassen ohne UNICODE . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2. Buchstabenklassen mit UNICODE . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
61
7.1. Bedeutungen von Zugriffsrechten . . . . . . . .
7.2. Ändern mit einer Oktalzahl/Maske . . . . . . .
7.3. Linux-Befehle: Dokumentation, Dateien, Pfade
7.4. Linux-Befehle: Textverarbeitung . . . . . . . .
7.5. Linux-Befehle: Komprimieren . . . . . . . . . .
7.6. Linux-Befehle: Dateisystem . . . . . . . . . . .
7.7. Linux-Befehle: Prozessmanagement und User .
7.8. Linux-Befehle: Zeichensätze . . . . . . . . . . .
7.9. Linux-Befehle: Umgebungsvariablen . . . . . .
7.10. Linux-Befehle: Netzwerkeigenschaften . . . . .
7.11. Linux-Befehle: Rechner fernsteuern . . . . . . .
7.12. Linux-Befehle: Operatoren . . . . . . . . . . . .
7.13. Linux-Befehle: Versionsverwaltung . . . . . . .
7.14. Linux-Befehle: Sonstiges . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
9
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
112
113
123
123
124
124
125
126
126
126
127
127
127
128
131
A. Anhang
A.1. Die Backus-Naur-Form (BNF)
Die Backus-Naur-Form wurde zum ersten Mal bei der Defintion von Algol 60 verwendet.
Ein Programm besteht aus speziellen Wortsymbolen wie for, if usw., sogenannten terminalen Symbolen. Die terminalen Symbole werden zu komplexeren Gebilden kombiniert, die dann das eigentliche
Programm ergeben. Jedes Gebilde nennt man syntaktische Kategorie oder nicht-terminales Symbol
der Sprache.
Die Syntaxdefinition einer Sprache legt fest, wie diese terminalen und nichtterminalen Symbole
kombiniert werden dürfen. Dazu gibt es eine Menge von Produktionen.
Die Syntax einer Sprache ist die Menge aller Terminalsymbole, syntakischen Kategorien und Menge
der Produktionen.
Die BNF besteht aus
• Terminalsymbolen: festen Namen, Konstanten
• Nichtterminalen Symbolen: eingeschlossen in „< “und „> “
• Metasymbolen
– ::= entspricht, kann ersetzt werden:
z.B. <Zahl>:: = 1
– | oder
z.B. <Zahl>:: = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0
– {} Wiederholung: Nullmal oder mehrmal:
z.B. <Variablenname>:: = <Buchstabe> { <Ziffer> | <Buchstabe> }
Bemerkung:
manchmal werden den geschweiften Klammern * oder + hochgestellt, das bedeutet:bei
*: die Wiederholung der eingeschlossenen Elemente kann auch Nullmal sein. bei +: Die
Wiederholung der eingeschlossenen Elemente muß mindestens einmal sein.
Beispiel: Teile der Definition von PERL in BNF
• compound-statement
compound - statement
::= '{ ' < statement - list > '} '
statement - list
::= < empty >
::= < statement >
::= < statement > < statement - list >
Abbildung A.1.: compond-statement
132
A.1. Die Backus-Naur-Form (BNF)
– expression-statement-statement
expression - statement
::= < expression > '; '
Abbildung A.2.: expression-statement
– if-statement
if - statement
::= 'if ' '( ' < expression > ') ' < compound - statement >
::= < simple - statement > 'if ' < expression >
Abbildung A.3.: if-statement
– while-statement
while - statement
::= ' while ' '( ' < expression > ') ' < compound - statement >
::= < simple - statement > ' while ' < expression >
Abbildung A.4.: while-statement
– for-statement
for - statement
::= 'for ' '( ' <for - initialization > '; ' <for - control > '; '
<for - iteration > ') ' < statement >
for - initialization
::= < empty >
::= < expression >
for - control
::= < empty >
::= < expression >
for - iteration
::= < empty >
::= < expression >
Abbildung A.5.: for-statement
133
134
A. Anhang
– do-statement
do - statement ::= 'do ' < statement > ' while ' '( ' < expression > ') ' '; '
Abbildung A.6.: do-statement
Index
Ablaufsteuerungsanweisungen
do until, 31
do while, 31
foreach, 32
for, 32
if...else, 28
while, 29
if, 28
Ausdrücke, 18
Arithmetische Ausdrücke, 18
Logische Ausdrücke, 23–24
Wahrheitswerttabelle, 24
Block, 27
Datei einlesen
STDIN, 20
close, 34
open, 34
Dateinhandle, 34
Diamondoperator, 34
Filepositionmarker, 35
Datei schreiben, 35
STDOUT, 20
Datenstrukturen, 15
Hashes, 53–55
key, 53
Neues Element einfuegen, 54
sort, 54
value, 53
Zugriff auf Elemente eines Hashes, 53
Liste, 15
Zugriff auf Elemente einer Liste, 16
Skalar, 15
Der Dateibaum im LINUX, 99
Der Symbolic Link, 114
Fachbegriffliche Abkürzungen, 10
Formatierungskonvention, 17, 19, 27, 28, 31, 66
Interne Repräsentation von Zahlen
Binärsystem, 36–37
Dezimalsystem, 36
Hexadezimalsystem, 37
Konvention für Dateinamen, 104
Man bzw. info pages bei Linux, 115
Operatoren, 23
Arithmetische Operatoren, 23
modulo, 23
string Operatoren, 23
Konkatenationsoperator, 23
Vervielfältigungsoperator, 23
Vergleichsoperatoren, 24
Vergleichsoperatoren bei Strings, 24
eq, 24
le, 24
lt, 24
ne, 24
qe, 24
qt, 24
Piping bzw. redirecting, 116
Programmaufbau, 12–13
ident line, 12
use strict, 17
Programm editieren, 13
Editor, 13
Programm starten, 13
Programmaufruf, 13
Reguläre Ausdrücke, 57–65
Ausschalten der Metazeichen, 59
Binding Operator, 57
Buchstabenklassen mit UNICODE, 60
Buchstabenklassen ohne UNICODE, 60
Definition, 57
globales Suchen, 62
Greedy-Nongreedy Verhalten, 63
Gruppierung, 61
Metazeichen, 57
Anfang der Zeile, 59
Buchstabenbereich, 58
Ende der Zeile, 59
negierte Buchstabenbereiche, 60
Quantifizierung, 58
Wildcard, 58
Zeichengruppierung, 59
substitute, 63
Relative und absolute Datei- oder Verzeichnisbezeichnu
Shellscript, 120
Subroutinen, 73
Übergabe des Argumentwerts, 77
Übergabemechanismus im Detail, 83
Datenaustausch, 74
Definition, 74
Gültigkeitsbereich von Variablen, 77
Iterativ, 83
Lokale Variablen, 76
my, 76
135
136
Index
Rekursion, 82
Probleme, 78
Wochenttagsprogramm, 85
Systemroutinen, 66
chomp, 21
chr, 68
join, 69
length, 68
ord, 67
pop, 69
push, 70
reverse, 71
scalar, 68
sort, 72
split, 66
unshift, 71
Texte Editieren mit Kate im LINUX, 105
Tokenisierung, Sortieren, Frequenzlisten mit LiNUX-Befehle, 118–120
Translate von Zeichen mit LiNUX-Befehle, 118
UNICODE
Escape-Sequenz, 61
Variable, 16
$_, 51
@_ , 84
Deklaration, 17
Globale Variablen, 82
our, 82
Initialisierung, 18
Wertzuweisung, 19
Variablen
Skalar, 57
Verwaltung von Dateien im LINUX
Archive anlegen, 117
Das Anlegen von Dateien, 100
Das Anzeigen von Dateien, 102
Das Anzeigen von Inhaltsverzeichnissen, 101
Das Kopieren und Umbenennen von Dateien, 103
Das Löschen von Dateien, 101
Das Verwalten von Verzeichnisse, 102
Finden von Unterschieden in Dateien, 118
Komprimieren von Dateien, 117
Zeichenkodierung
-C, 49
binmode, 49
use locale, 47
use open utf8, 50
use utf8, 46
ASCII, 39
ISO Latin-1, 40–43
UNICODE, 43–44
UTF-8, 44–46
Zugriffsrechte unter Linux, 112–113
Index
137