Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
Shell-Programmierung von Jürgen Wolf
Einführung, Praxis, Referenz
Buch: Shell-Programmierung

Shell-Programmierung
782 S., mit CD, 44,90 Euro
Rheinwerk Computing
ISBN 3-89842-683-1
gp Kapitel 2 Variablen
  gp 2.1 Grundlagen
    gp 2.1.1 Zugriff auf den Wert einer Variablen
    gp 2.1.2 Variablen-Interpolation
  gp 2.2 Zahlen
    gp 2.2.1 Integer-Arithmetik (Bourne-Shell, Bash und Korn-Shell)
    gp 2.2.2 Integer-Arithmetik (Bash und Korn-Shell only)
    gp 2.2.3 bc – Rechnen mit Fließkommazahlen und mathematische Funktionen
  gp 2.3 Zeichenketten
    gp 2.3.1 Stringverarbeitung
    gp 2.3.2 Erweiterte Funktionen für Bash und Korn-Shell
  gp 2.4 Quotings und Kommando-Substitution
    gp 2.4.1 Single und Double Quotings
    gp 2.4.2 Kommando-Substitution – Back Quotes
  gp 2.5 Arrays (Bash und Korn-Shell only)
    gp 2.5.1 Werte an Arrays zuweisen
    gp 2.5.2 Eine Liste von Werten an ein Array zuweisen (Bash)
    gp 2.5.3 Eine Liste von Werten an ein Array zuweisen (Korn-Shell)
    gp 2.5.4 Zugreifen auf die einzelnen Elemente eines Arrays
  gp 2.6 Variablen exportieren
  gp 2.7 Umgebungsvariablen eines Prozesses
  gp 2.8 Shell-Variablen
  gp 2.9 Automatische Variablen der Shell
    gp 2.9.1 Der Name des Shellscripts – $0
    gp 2.9.2 Die Prozessnummer des Shellscripts – $$
    gp 2.9.3 Der Beendigungsstatus eines Shellscripts – $?
    gp 2.9.4 Die Prozessnummer des zuletzt gestarteten Hintergrundprozesses – $!
    gp 2.9.5 Weitere vordefinierte Variablen der Shell
    gp 2.9.6 Weitere automatische Variablen für Bash und Korn-Shell


Rheinwerk Computing

2.3 Zeichenkettedowntop

Zum Bearbeiten von Zeichenketten werden immer noch vorrangig die alten UNIX-Tools (sofern auf dem System vorhanden) wie tr, cut, paste, sed und natürlich awk verwendet. Sofern Ihr Script überall laufen soll, sind Sie mit diesen Mitteln immer auf der sicheren Seite. Im Gegensatz zur Bourne-Shell bieten Ihnen hierzu die Bash und die Korn-Shell auch einige eingebaute Funktionen an.


Rheinwerk Computing

2.3.1 Stringverarbeitung  downtop

Ich möchte Ihnen zunächst die grundlegenden UNIX-Kommandos zur Stringverarbeitung ans Herz legen, mit denen Sie auf jeder Shell arbeiten können, also auch der Bourne-Shell.

Schneiden mit cut

Müssen Sie aus einer Datei oder der Ausgabe eines Befehls bestimmte Datenfelder extrahieren (herausschneiden), leistet Ihnen das Kommando cut sehr gute Dienste. Die Syntax von cut sieht wie folgt aus:

cut -option datei

Würden Sie bspw. das Kommando folgendermaßen verwenden

you@host > cut -c5 gedicht.txt

dann würden Sie aus der Textdatei gedicht.txt jeweils aus jeder Zeile das fünfte Zeichen extrahieren. Die Option –c steht für character (also Zeichen). Wollen Sie hingegen aus jeder Zeile einer Datei ab dem fünften Zeichen bis zum Zeilenende alles extrahieren, dann wird cut wie folgt verwendet:

you@host > cut -c5- gedicht.txt

Wollen Sie aus jeder Zeile der Datei alles ab dem fünften bis zum zehnten Zeichen herausschneiden, dann sieht die Verwendung des Kommandos so aus:

you@host > cut -c5–10 gedicht.txt

Natürlich lassen sich auch mehrere einzelne Zeichen und Zeichenbereiche mit cut heraustrennen. Hierfür müssen Sie ein Komma zwischen den einzelnen Zeichen bzw. Zeichenbereichen setzen:

you@host > cut -c1,3,5,6,7–12,14 gedicht.txt

Hiermit würden Sie das erste, dritte, fünfte, sechste, siebte bis zwölfte und das vierzehnte Zeichen aus jeder Zeile extrahieren.

Häufig wird das Kommando cut in Verbindung mit einer Pipe verwendet, sprich cut erhält die Standardeingabe von einem anderen Kommando und nicht von einer Datei. Einfachstes Beispiel ist das Kommando who:

you@host > who
sn       pts/0     Feb  5 13:52 (p83.129.9.xxx.tisdip.tiscali.de)
mm       pts/2     Feb  5 15:59 (p83.129.4.xxx.tisdip.tiscali.de)
kd10129  pts/3     Feb  5 16:13 (pd9e9bxxx.dip.t-dialin.net)
you      tty01     Feb  5 16:13 (console)
you@host > who | cut -c1–8
sn
mm
kd10129
you

Hier wurden zum Beispiel aus dem Kommando who die Benutzer (die ersten 8 Zeichen) auf dem System extrahiert. Wollen Sie hingegen den Benutzernamen und die Uhrzeit des Logins extrahieren, so ist dies mit cut kein Problem:

you@host > who | cut -c1–8,30–35
sn      13:52
mm      15:59
kd10129 16:13

cut lässt Sie auch nicht im Stich, wenn die Daten nicht so ordentlich in Reih und Glied aufgelistet sind, wie dies eben bei who der Fall war. Folgendes sei gegeben:

you@host > cat datei.csv
tot;15:21;17:32;
you;18:22;23:12;
kd10129;17:11;20:23;

Dies soll eine Login-Datei darstellen, die zeigt, welcher Benutzer von wann bis wann eingeloggt war. Um hier bestimmte Daten zu extrahieren, bieten sich die Optionen –d (Abk. für delimiter = Begrenzungszeichen) und –f (Abk. für field = Feld) an. Im Beispiel besteht das Begrenzungszeichen aus einem Semikolon (;). Wollen Sie bspw. nur die Benutzer (Feld 1) aus dieser Datei extrahieren, gehen Sie mit cut so vor:

you@host > cut -d\; -f1 datei.csv
tot
you
kd10129

Um die Sonderbedeutung des Semikolons abzuschalten, wurde hier ein Backslash verwendet. Wollen Sie hingegen den Benutzer und die Auslogg-Zeit extrahieren, dann erreichen Sie dies folgendermaßen:

you@host > cut -d\; -f1,3 datei.csv
tot;17:32
you;23:12
kd10129;20:23

Hinweis   Setzen Sie cut ohne die Option -d ein, wird das Tabulatorzeichen standardmäßig als Begrenzungszeichen verwendet.


Einfügen mit paste

Das Gegenstück zu cut ist das Kommando paste (paste = kleben), womit Sie etwas in Zeilen einfügen bzw. zusammenfügen können. Einfachstes Beispiel:

you@host > cat namen.txt
john
bert
erni
flip
you@host > cat nummer.txt
(123)12345
(089)234564
(432)4534
(019)311334
you@host > paste namen.txt nummer.txt > zusammen.txt
you@host > cat zusammen.txt
john    (123)12345
bert    (089)234564
erni    (432)4534
flip    (019)311334

Hier wurden die entsprechenden Zeilen der Dateien namen.txt und nummern.txt zusammengefügt und die Ausgabe in die Datei zusammen.txt umgeleitet. Natürlich können Sie auch mehr als nur zwei Dateien zeilenweise zusammenfügen. Wollen Sie auch noch ein anderes Begrenzungszeichen verwenden, kann mit der Option –d ein entsprechendes Zeichen eingesetzt werden.

Der Filter tr

Häufig verwendet wird der Filter tr, mit dem Sie einzelne Zeichen aus der Standardeingabe übersetzen können. Die Syntax:

tr von_Zeichen nach_Zeichen

Bei den Argumenten »von_Zeichen« und »nach_Zeichen« können Sie ein einzelnes oder mehrere Zeichen verwenden. Dabei wird jedes Zeichen »von_Zeichen«, das aus der Standardeingabe kommt, übersetzt in »nach_Zeichen«. Die Übersetzung erfolgt wie gehabt auf die Standardausgabe. Als Beispiel soll folgendes Gedicht verwendet werden:

you@host > cat gedicht.txt
Schreiben, wollte ich ein paar Zeilen.
Buchstabe für Buchstabe reihe ich aneinand.
Ja, schreiben, meine Gedanken verweilen.
Wort für Wort, es sind mir viele bekannt.
Satz für Satz, geht es fließend voran.
Aber um welchen transzendenten Preis?
Was kostet mich das an Nerven, sodann?
An Kraft, an Seele, an Geist und Fleiß?
(von Brigitte Obermaier alias Miss Zauberblume)

Wollen Sie jetzt hier sinnloserweise jedes »a« durch ein »b« ersetzen, geht das so:

you@host > tr a b < gedicht.txt
Schreiben, wollte ich ein pbbr Zeilen.
Buchstbbe für Buchstbbe reihe ich bneinbnd.
Jb, schreiben, meine Gedbnken verweilen.
Wort für Wort, es sind mir viele bekbnnt.
Sbtz für Sbtz, geht es fließend vorbn.
Aber um welchen trbnszendenten Preis?
Wbs kostet mich dbs bn Nerven, sodbnn?
An Krbft, bn Seele, bn Geist und Fleiß?
(von Brigitte Obermbier blibs Miss Zbuberblume)

Nun ein etwas sinnvolleres Beispiel. Erinnern Sie sich an folgenden cut-Befehl:

you@host > cut -d\; -f1,3 datei.csv
tot;17:32
you;23:12
kd10129;20:23

Die Ausgabe hier ist nicht unbedingt schön leserlich. Hier würde sich der Filter tr mit einer Pipe hervorragend eignen. Schieben wir doch einfach in die Standardeingabe von tr die Standardausgabe von cut und ersetzen das Semikolon durch ein Tabulatorzeichen (\t):

you@host > cut -d\; -f1,3 datei.csv | tr \; '\t'
tot     17:32
you     23:12
kd10129 20:23

Dies sieht doch schon um einiges besser aus. Natürlich muss auch hier das Semikolon mit einem Backslash ausgegrenzt werden. Ebenso können Sie hier wieder ganze Zeichenbereiche verwenden, wie Sie dies von der Shell (Stichwort: Wildcards) her kennen.

you@host > tr '[a-z]' '[A-Z]' < gedicht.txt
SCHREIBEN, WOLLTE ICH EIN PAAR ZEILEN.
BUCHSTABE FüR BUCHSTABE REIHE ICH ANEINAND.
JA, SCHREIBEN, MEINE GEDANKEN VERWEILEN.
WORT FüR WORT, ES SIND MIR VIELE BEKANNT.
SATZ FüR SATZ, GEHT ES FLIEßEND VORAN.
ABER UM WELCHEN TRANSZENDENTEN PREIS?
WAS KOSTET MICH DAS AN NERVEN, SODANN?
AN KRAFT, AN SEELE, AN GEIST UND FLEIß?
(VON BRIGITTE OBERMAIER ALIAS MISS ZAUBERBLUME)

Damit allerdings hier auch der Filter tr diese Zeichenbereiche erhält und nicht unsere Shell daraus eine Datei-Expansion macht, müssen Sie diese Zeichenbereiche für tr zwischen einfache Anführungsstriche setzen.

Wollen Sie bestimmte Zeichen aus dem Eingabestrom löschen, so können Sie die Option –d verwenden:

you@host > tr -d ' ','\n' < gedicht.txt
SchreibenwollteicheinpaarZeilen.BuchstabefürBuchstabereiheichaneinand.
JaschreibenmeineGedankenverweilen. WortfürWortessindmirvielebekannt.
SatzfürSatzgehtesfließendvoran.AberumwelchentranszendentenPreis?
WaskostetmichdasanNervensodann?AnKraftanSeeleanGeistundFleiß?
(vonBrigitteObermaieraliasMissZauberblume)

Hier wurden alle Leer- und Newline-Zeichen (Zeilenumbrüche) gelöscht. Mehrere Zeichen werden – wie Sie sehen – mit einem Komma voneinander getrennt.

Und noch eine gern genutzte Option von tr ist mit –s gegeben. Damit können Sie mehrfach hintereinander kommende gleiche Zeichen durch ein anderes austauschen. Dies wird etwa verwendet, wenn in einer Datei unnötig viele Leerzeichen oder Zeilenumbrüche vorkommen. Kommen in einer Textdatei unnötig viele Leerzeichen hintereinander vor, so können Sie diese folgendermaßen durch ein einzelnes Leerzeichen austauschen:

you@host > tr -s ' ' ' ' < datei.txt

Gleicher Fall mit unnötig vielen Zeilenumbrüchen:

you@host > tr -s '\n' '\n' < datei.txt

Die Killer-Tools – sed, awk und reguläre Ausdrücke

Die absoluten Killer-Tools für die Textverarbeitung stehen Ihnen mit awk und sed zur Verfügung. Bei der Verwendung von sed, awk, grep und vielen anderen UNIX-Tools kommen Sie auf Dauer um die regulären Ausdrücke nicht herum. Sollten Sie also eine Einführung in diese UNIX-Tools benötigen, so sollten Sie sich die Kapitel 11, 12 und 13 ansehen.

Auf die Schnelle soll hier dennoch die Verwendung von awk und sed in der Shell demonstriert werden. Wollen Sie bspw. mit awk die Länge einer Zeichenkette ermitteln, so ist dies mit eingebauten (String-)Funktionen von awk kein Problem.

you@host > zeichen="juergen wolf"
you@host > echo $zeichen | awk '{print length($zeichen)}'
12

Hier schieben Sie über eine Pipe die Standardausgabe von echo an die Standardeingabe von awk. Im Anweisungsblock von awk wird dann der Befehl print (zur Ausgabe) verwendet. print gibt dabei die Länge (awk-Funktion length) der Variablen zeichen aus. In einem Shellscript werden Sie allerdings selten die Länge oder den Wert eines Kommandos ausgeben wollen, sondern meistens damit weiterarbeiten. Um dies zu realisieren, wird wieder die Kommando-Substitution verwendet.

# Demonstriert das Kommando awk im Shellscript
# Name : aawk
zeichen="juergen wolf"
laenge=`echo $zeichen | awk '{print length($zeichen)}'`
echo "$zeichen enthaelt $laenge Zeichen"

Das Beispiel bei der Ausführung:

you@host > ./aawk
juergen wolf enthaelt 12 Zeichen

Neben der Funktion length() stehen Ihnen noch eine Reihe weiterer typischer Stringfunktionen mit awk zur Verfügung. Aus Referenz-Gründen werden diese in Tabelle 2.3 aufgelistet. Die Anwendung dieser Funktionen entspricht im Prinzip derjenigen, die Sie eben mit length() gesehen haben. Sofern Ihnen awk noch nicht so richtig von der Hand gehen sollte, empfehle ich Ihnen, zunächst Kapitel 13, awk-Programmierung, zu lesen.


Tabelle 2.3   Awks Builtin-Stringfunktionen

Funktion Bedeutung
tolower str Komplette Zeichenkette in Kleinbuchstaben
toupper str Komplette Zeichenkette in Großbuchstaben
index(str, substr) Gibt die Position zurück, wo substr in str anfängt
match(str, regexpr) Überprüft, ob der reguläre Ausdruck regexpr in str enthalten ist
substr(str, start, len) Gibt einen Teilstring ab Postion start mit der Länge len aus str zurück.
split(str, array, sep) Teilt einen String in einzelne Felder auf und gibt diese an ein Array. sep dient dabei als Feldtrenner.
gsub(alt, neu, str) Ersetzt in str den String alt durch neu
sub(alt, neu, str) Ersetzt erstes Vorkommen von alt durch neu in str
sprintf("fmt",expr) Verwendet die printf-Formatbeschreibung für expr

Neben awk will ich Ihnen hier auch kurz den Einsatz von sed auf Zeichenketten zeigen. sed wird vorzugsweise eingesetzt, um aus ganzen Textdateien bestimmte Teile herauszufiltern, zu verändern oder zu löschen. Auch hier geht man mit einer Pipe zu Werke. Will man eine ganze Textdatei durch sed jagen, geht man folgendermaßen vor:

you@host > cat gedicht.txt | sed 's/Satz/Wort/g'

Hier wird die Ausgabe von cat durch eine Pipe an die Eingabe von sed weitergegeben. sed ersetzt jetzt jedes Wort »Satz« durch das Wort »Wort« und gibt die Ersetzung an die Standardausgabe aus. s steht hier für substitute und das Suffix g für global, was bedeutet, dass die Ersetzung nicht nur einmal, sondern im kompletten Text, also auch bei mehrfachen Vorkommen, umgesetzt wird. Natürlich wird auch hier bevorzugt die Kommando-Substitution im Shellscript verwendet.

# Demonstriert sed im Shellscript
# Name : ased
zeichenkette="... und sie dreht sich doch"
neu=`echo $zeichenkette | sed 's/sie/die Erde/g'`
echo $neu

Das Shellscript bei der Ausführung:

you@host > ./ased
... und die Erde dreht sich doch

Dies sollte als Kurzeinstieg zu den Power-Tools sed und awk genügen. Mehr dazu finden Sie in Kapitel 12, Der Stream-Editor sed, und 13, awk-Programmierung.


Rheinwerk Computing

2.3.2 Erweiterte Funktionen für Bash und Korn-Shell  toptop

Der Bash und der Korn-Shell wurden im Gegensatz zur Bourne-Shell für die Stringverarbeitung einige extra Funktionen spendiert, welche allerdings in keiner Weise die eben vorgestellten UNIX-Tools ersetzen. Hierbei handelt es sich höchstens um einige Abkürzungen.

Länge eines Strings

Wenn Sie in der Bash oder Korn-Shell nicht auf awk zurückgreifen wollen, können Sie hier die Länge eines Strings mit folgender Syntax ermitteln:

$(#zeichenkette)

In der Praxis sieht dies folgendermaßen aus:

you@host > zeichenkette="... keep alive"
you@host > echo "Laenge von $zeichenkette ist ${#zeichenkette}"
Laenge von ... keep alive ist 14

Aneinanderreihen von Strings

Die Aneinanderreihung von Strings ist recht einfach. Hier müssen Sie lediglich die einzelnen Variablen hintereinander schreiben und mit einer Begrenzung versehen.

you@host > user=you
you@host > login=15:22
you@host > logout=18:21
you@host > daten=${user}:${login}_bis_${logout}
you@host > echo $daten
you:15:22_bis_18:21

(Teil-)String entfernen

Um einen bestimmten (Teil-)String oder besser ein Muster (weil hier auch die Metazeichen *, ? und [ ] verwendet werden können) aus einem String zu entfernen, bieten Ihnen Bash und Korn-Shell einige interessante Funktionen an. Aufgrund ihrer etwas umständlicheren Nutzung werden sie recht selten verwendet (siehe Tabelle 2.4).


Tabelle 2.4   Stringfunktionen von Bash und Korn-Shell

Funktion Gibt zurück ...
${var#pattern} … den Wert von var ohne kleinstmöglichen durch pattern abgedeckten linken Teilstring. Bei keiner Abdeckung wird der Inhalt von var zurückgegeben.
${var##pattern} … den Wert von var ohne größtmöglichen durch pattern abgedeckten linken Teilstring. Bei keiner Abdeckung wird der Inhalt von var zurückgegeben.
${var%pattern} … den Wert von var ohne kleinstmöglichen durch pattern abgedeckten rechten Teilstring. Bei keiner Abdeckung wird der Inhalt von var zurückgegeben.
${var%%pattern} … den Wert von var ohne größtmöglichen durch pattern abgedeckten rechten Teilstring. Bei keiner Abdeckung wird der Inhalt von var zurückgegeben.

Hierzu ein Shellscript, das diese Funktionen demonstriert:

# Name : acut
var1="1234567890"
var2="/home/you/Dokuments/shell/kapitel2.txt"
pfad=${var2  %/*}
file=${var2##*/}
echo "Komplette Angabe: $var2"
echo "Pfad            : $pfad"
echo "Datei           : $file"
# rechts 2 Zeichen abschneiden
echo ${var1  %??}
# links 2 Zeichen abschneiden
echo ${var1#??}
# im Klartext ohne Metazeichen
echo ${var2  %/kapitel2.txt}

Das Script bei der Ausführung:

you@host > ./acut
Komplette Angabe: /home/you/Dokuments/shell/kapitel2.txt
Pfad            : /home/you/Dokuments/shell
Datei           : kapitel2.txt
12345678
34567890
/home/you/Dokuments/shell

Die Metazeichen *, ? und [ ] können Sie hierbei genauso einsetzen, wie Sie dies bereits von der Datei-Expansion her kennen. Zugegeben, sehr lesefreundlich sind diese Funktionen nicht gerade, aber in Verbindung mit einer Pfadangabe, wie im Beispiel gesehen, lässt es sich recht gut damit leben.

String rechts oder links abschneiden (Korn-Shell only)

Die Korn-Shell bietet Ihnen die Möglichkeit, bei einem String von der rechten oder linken Seite etwas abzuschneiden. Hierzu verwendet man wieder den Befehl typeset. Natürlich lässt typeset schlussfolgern, dass hierbei nicht im eigentlichen Sinneabgeschnitten wird, sondern Sie deklarieren lediglich die Länge einer Variablen, also welche Anzahl von Zeichen diese aufnehmen darf, beispielsweise:

you@host > typeset -L5 atext
you@host > atext=1234567890
you@host > echo $atext
12345

Hier definieren Sie die Länge der Variablen »atext« auf 5 Zeichen. Die Option –L steht dabei für eine linksbündige Ausrichtung, was allerdings bei einem leeren String keinen Effekt hat. Damit könnten Sie praktisch mit –L eine Zeichenkette links um n Zeichen abschneiden. Die Gegenoption, um von der rechten Seite etwas zu entfernen, lautet –Rn. Mit n geben Sie die Anzahl der Zeichen an, die Sie von der rechten Seite abschneiden wollen. Hier typset im Einsatz:

you@host > zeichenkette=1234567890
you@host > typeset -L5 zeichenkette
you@host > echo $zeichenkette
12345
you@host > typeset -R3 zeichenkette
you@host > echo $zeichenkette
345

(Teil-)Strings ausschneiden (Bash only)

Als einzige von allen Shells bietet Ihnen die Bash eine sinnvolle Funktion an, um aus einem String Teile herauszuschneiden (ähnlich wie mit dem Kommando cut). Auch die Anwendung ist recht passabel und lesefreundlich. Die Syntax:

${var:start:laenge}
${var:start}

Damit schneiden Sie aus der Variablen var ab der Position start, laenge Zeichen heraus. Erfolgt keine Angabe zu laenge, wird von der Position start bis zum Ende alles herauskopiert.

you@host > zeichenkette=1234567890
you@host > echo ${zeichenkette:3:6}
456789
you@host > echo ${zeichenkette:5}
67890
you@host > neu=${zeichenkette:5:3}
you@host > echo $neu
678
you@host > mehr=${zeichenkette:5:1}_und_${zeichenkette:8:2}
you@host > echo $mehr
6_und_90


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
 << zurück
  
  Zum Katalog
Zum Katalog: Shell-Programmierung
Shell-Programmierung
bestellen
 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-Server






 Linux-Server


Zum Katalog: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Katalog: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Katalog: Linux Handbuch






 Linux Handbuch


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de