Reguläre Ausdrücke in Shell
Marc Reichelt
- programmiertechnik
Hallo an alle,
in einer Linux-Shell versuche ich mich etwas an regulären Ausdrücken, die ich für eine bestimmte Automatisierung brauche.
Derzeit scheitere ich an einem kleinen Problem, auch eine halbe Stunde Googeln hat mich leider nicht weitergebracht.
Ich habe eine Datei namens "Datei", in dieser stehen ganz viele Zeilen, unter anderem auch diese:
startINHALTende
Wenn ich nun folgendes Kommando in der Shell ausführe, bekomme ich die Zeile zurück:
grep 'start.*ende' Datei
Ich möchte aber nicht die ganze Zeile, sondern nur INHALT zurück bekommen, also ausschließlich das was zwischen "start" und "ende" steht.
Und das Ganze soll dann in einer Shell-Variablen gespeichert werden, denn schließlich wird das Ganze nicht von Hand, sondern via Shell-Skript ausgeführt.
Vielen Dank im Voraus für eure Mühe!
Marc Reichelt || http://www.marcreichelt.de/
Hallo nochmals,
ich habe mittlerweile einen Befehl finden können, der mir nur INHALT ausgibt. Er lautet:
expr "cat Datei
" : 'start*([^ ]*)ende'
Jetzt habe ich nur noch ein Problem, nämlich den, dass ich die Ausgabe (also "INHALT") in einem Shellskript einer Variable zuweisen möchte, folgendes klappt leider nicht:
var=expr "cat Datei
" : 'start*([^ ]*)ende'
Gibt's hier vielleicht einen Meister der Shellprogrammierung, der mir hierbei helfen kann?
Vielleicht gibt's ja auch eine wesentlich bessere und schnellere Lösung?
Bis dann!
Marc Reichelt || http://www.marcreichelt.de/
hallo Marc,
Gibt's hier vielleicht einen Meister der Shellprogrammierung, der mir hierbei helfen kann?
Ich bin mit Sicherheit kein solcher "Meister", aber ich rate dir dringlich, dich mit pipes zu beschäftigen. Das dürfte dein Problem lösen.
Grüße aus Berlin
Christoph S.
Hallo Christoph,
Gibt's hier vielleicht einen Meister der Shellprogrammierung, der mir hierbei helfen kann?
Ich bin mit Sicherheit kein solcher "Meister", aber ich rate dir dringlich, dich mit pipes zu beschäftigen. Das dürfte dein Problem lösen.
Hmm, ich arbeite das Ganze jetzt mit PHP ab.
Das wollte ich zwar ursprünglich nicht machen, führt mich aber dennoch wesentlich schneller ans Ziel - und schließlich kann man PHP ja auch ganz einfach auf der Konsole ausführen... ;-)
Bis dann!
Marc Reichelt || http://www.marcreichelt.de/
hi,
Hmm, ich arbeite das Ganze jetzt mit PHP ab.
Na gut, wenn das für deine Zwecke ausreicht ...
Aber Shellprogrammierung ist schon eine tolle Sache. Man kann ja Shellscripts in der Form "script.sh" auch als CGI-Scripts ausführen lassen, was bisweilen deutlich bequemer als Perl oder PHP ist (PHP kann bisher auf Systemebene noch nicht so viel wie Perl).
Ich habe nicht aufgepaßt bzw. vergessen (wenn ich es denn gelesen habe), welches System du grade hast. Und Shells gibts ja auch mehrere, allerdings sind (nach allem, was ich bisher weiß) Shellscripts auf allen mit etwa demselben Erfolg einsetzbar. Schau einfach mal in dein System, besonders in die eventuell vorhandenen Unterverzeichnisse unter /etc. Da (oder auch an anderen Stellen im System) wirst du etliche Shellscripts finden, die du zum Vergleich studieren kannst.
Grüße aus Berlin
Christoph S.
Hallo Marc
var=expr "
cat Datei
" : 'start*([^ ]*)ende'
Hilft eventuell: set var=...
Auf Wiederlesen
Detlef
hallo Detlef,
Hilft eventuell: set var=...
Nein. Siehe "man set". "set" ist für Umgebungsvariablen da, aber in der Shellprogrammierung steht es nicht zur Verfügung.
Grüße aus Berlin
Christoph S.
(im Zweifelsfall CK fragen ;-))
hallo Marc,
in einer Linux-Shell versuche ich mich etwas an regulären Ausdrücken
Naja, die Überschrift deines postings ist sinnvoll und zum Inhalt der Frage passend, aber ich vermisse jetzt ein bißchen den Regulären Ausdruck, um den es dir gehen könnte ;-)
Ich habe eine Datei namens "Datei", in dieser stehen ganz viele Zeilen, unter anderem auch diese:
startINHALTende
Hm, das ist möglich. Du solltest vielleicht der besseren Übersicht wegen dafür sorgen, daß da Leerzeichen reinkommen, also
start INHALT ende
Wenn ich nun folgendes Kommando in der Shell ausführe, bekomme ich die Zeile zurück:
grep 'start.*ende' Datei
ups? bitte mal "man grep" vergleichen und/oder die Voraussetzungen genauer benennen. Du bist bereits in dem Verzeichnis, in dem "datei" liegt? Und wie ist deine Zeile
grep 'start.*ende' Datei
zu deuten?
Ich möchte aber nicht die ganze Zeile, sondern nur INHALT zurück bekommen, also ausschließlich das was zwischen "start" und "ende" steht.
Du kannst an "grep" eine pipe anhängen resp. grep gleich "in die pipe" stopfen. Das heißt, was grep findet, kannst du sofort danach mit einem Regulären Ausdruck prüfen oder eben ausgeben lassen. Schematisch ungefähr so:
grep 'datei' /'start'(.*)'ende'/ | 'tu irgendwas'
_bitte beachten_: so funktioniert das selbstverständlcih auch nicht. Es ist nur das ungefähre Schema.
Grüße aus Berlin
Christoph S.
Hallo Marc
Ich habe eine Datei namens "Datei", in dieser stehen ganz viele Zeilen, unter anderem auch diese:
startINHALTendeWenn ich nun folgendes Kommando in der Shell ausführe, bekomme ich die Zeile zurück:
grep 'start.*ende' Datei
Ich möchte aber nicht die ganze Zeile, sondern nur INHALT zurück bekommen, also ausschließlich das was zwischen "start" und "ende" steht.
var=$(grep -o 'start.*ende' datei)
erg=$(expr match $dat 'start*([^ ]*)ende')
Die Variable erg enthält nun INHALT, Du kannst mit $erg auf die Variable zugreifen.
Freundliche Grüße
Vinzenz
Hallo Vinzenz,
Lese Ausgabe von grep in die Variable var ein
Parameter -o ist überflüssig, wenn die Zeile nur den Suchtext enthält
var=$(grep -o 'start.*ende' datei)
Werte den Ausdruck per Mustererkennung aus
erg=$(expr match $dat 'start*([^ ]*)ende')
Die Variable erg enthält nun INHALT, Du kannst mit $erg auf die Variable zugreifen.
Einen riesigen Dank, schon beim nächsten Skript werde ich deinen Tipp gut gebrauchen können! :-)
Freundliche Grüße
Marc Reichelt || http://www.marcreichelt.de/
hallo Marc,
noch eine Kleinigkeit:
var=$(grep -o 'start.*ende' datei)
erg=$(expr match $dat 'start*([^ ]*)ende')
Das ist der Hinweis von Vincent. Das funktioniert, wenn du beide Zeilen in ein Shellscript schreibst und das Script aufrufst. Ich war vorhin davon ausgegangen, daß du die einzelnen Anweisungen der Reihe nach in der Shell eintippst, und da funktioniert das auch, wenn du es als pipe hintereinander schreibst (ist getestet und für funktionsfähig befunden).
Grüße aus Berlin
Christoph S.