Re: Für die sed / RegExp Experten
On 2004.01.26 11:15, Matthias Hentges wrote:
Hallo Liste!
Ich lese mittlerweile seit zwei Stunden diverse sed HowTo's aber ich
bin
wohl irgendwie zu dumm.
Folgendes Problem:
echo "2.6.2-rc1-mm3"| sed s/\-mm[1-99]//
bringt als Ergebnis "2.6.2-rc1".
Ich möchte aber genau das Gegenteil erhalten, nähmlich
"-mm3"
Also quasi eine invertierte RegExp, wobei aber nur der "-mm[1-99]
Teil
des Strings bekannt ist.
Kenne mich mit sed-Syntax zwar nicht sonderlich aus, aber dafuer ein
bisschen mit PERL, und reg-exes sind ja vom Prinzip her eh ueberall
aehnlich. :-)
Zunaechst einmal a line recklessly stolen from Christoph Maurer
<christoph-maurer@gmx.de>:
echo "2.6.2-rc1-mm3"| sed "s/.*\(-mm[0-9]\{1,\}\)/\1/"
Ich verlasse mich einfach mal drauf, dass die Syntax bei ihm
stimmt. :-)
Könnte mir da jemand auf die Sprünge helfen? Möglichst mit Erklärung
:)
Ein Schubs in die richtige Richtung wäre schon genug.
Und jetzt auf meinem eigenen Mist gewachsen der Schubs:
s/expression 1/expression 2/ sucht in einer Zeichenkette nach dem
Ausdruck "expression 1" und ersetzt ihn mit "expression 2". Du hast
zwar in "2.6.2-rc1-mm3" korrekt nach "\-mm[1-99]" gesucht, das dann
aber mit nichts ersetzt.
Bei Christoph setzt sich der Suchstring so zusammen:
.* alles uninteressante, was vor dem gesuchten Teil des Ausdruckes
steht
-mm[0-9]{1,} der gesuchte Teil
Zwischen den eckigen Klammern ist ein Bereich erlaubter Zeichen
angegeben. Damit wird aber immer nur nach _einem_ Zeichen gesucht. [1-
99] wuerde zB nicht funktionieren, um "23" zu finden, weil die 99 eben
nicht fuer neunundneunzig steht, sondern einfach nur das Zeichen "9"
doppelt in der Liste erlaubter Zeichen vorkommt. Effektiv laesst du
also nur die Ziffern 1-9 zu, schliesst aber 0 aus. Ausserdem suchst du
nur nach einer einzigen Ziffer. Statt "23" wuerde also nur "2"
gefunden werden.
Christoph hat jetzt mit [0-9] den gueltigen Bereich um die 0 erweitert
und mit ein bisschen Magic umgeben:
Mit {1,} hat er festgelegt, dass das vorherstehende Zeichen mindestens
einmal vorkommen muss. Mit {1,3} haette er auch sagen koennen, dass es
mindestens einmal, jedoch nicht haeufiger als dreimal vorkommen darf;
und mit {2} muesste es genau zweimal vorkommen.
Den gesuchten Ausdruck hat er mit den runden Klammern als Teilausdruck
festgelegt, auf den er spaeter Bezug nehmen kann. Das macht er im
zweiten Teil mit \1:
s/.*\(-mm[0-9]\{1,\}\)/\1/
Die \1 ist eine interne Variable, die einfach die Position des
Ausdruckes in runden Klammern angibt. Der gesamte Ausdruck .*(-mm[0-9]
{1,}) wird also durch den ersten eingeklammerten Teilausdruck ersetzt.
Weil das so kompliziert ausgedrueckt ist, nochmal ein anderes Beispiel.
Deinen Suchausdruck koennte man zB folgendermassen schreiben:
/\(.*\)\(-\)\(mm[0-9]\{1,\}\)/
Dann waere:
\1 \(.*\)
\2 \(-\)
\3 \(mm[0-9]\{1,\}\)
Mit s/\(.*\)\(-\)\(mm[0-9]\{1,\}\)/\3\2\1/ koenntest du dann aus
"2.6.2-rc1-mm3" "mm3-2.6.2-rc1" machen...
Die manpage von SED war nicht wirklich erleuchtend....
Ich hoffe, etwas hilfreicher sein zu koennen. :-)
TIA
--
Matthias Hentges
Cologne / Germany
Schoenen Gruss,
Andreas
Reply to: