Sed Regex-Muster passte gierig, obwohl es nicht sollte

482
Oliver Friedrich

Ich bin über ein Verhalten gestolpert, das ich nicht erklären kann. Ich hoffe, einige von euch können mir helfen.

Ich versuche, eine Art Dokumentation aus einem größeren AntProjekt zu generieren. Als solches verwende ich seddie Informationen aus den Dateien, die ich später in der Dokumentation benötige.

Ich habe eine normale Ameisendatei mit folgenden Zeilen:

 <target name="targetA" depends="targetD" description="some fancy description"> ... <target name="targetB" depends="targetD" description="some fancy description"> ... <target name="targetC" depends="targetD" description="some fancy description"> 

Jetzt laufe ich mit dieser sed-Linie:

sed -nr 's/.*?target name="(.*?)".*="(.*?)".*/ * \1 - \2/p' 

Es sollte mir geben:

 * targetA - some fancy description * targetB - some fancy description * targetC - some fancy description 

Stattdessen bekomme ich:

 * targetA" depends="targetD" - some fancy description * targetA" depends="targetD" - some fancy description * targetA" depends="targetD" - some fancy description 

Ich habe versucht, die Ausgabe der zweiten Gruppe zu überspringen, um zu überprüfen, ob es sich um die erste Gruppe handelt, die tatsächlich mit dem gesamten "abhängigen" Teil übereinstimmt, obwohl ich den Regex bis zum nächsten doppelten Anführungszeichen nicht gierig eingestellt habe.

Was fehlt mir hier?

Die Verwendung eines expliziteren Regex wie diesem funktioniert wie erwartet, aber ich verstehe immer noch nicht die gierige Sache:

sed -nr 's/.*?target name="(.*?)".*=.*="(.*?)".*/ * \1 - \2/p' 

Da dies von Interesse sein könnte, verwende ich sed-4.2.2-4ubuntu1 für Ubuntu Linux (Standardinstallation)

0
sed reguläre Ausdrücke sind etwas eingeschränkter als Greps. Wenn Sie Regex kennen, können Sie einen Perl-One-Liner http://superuser.com/questions/416419/perl-for-matching-with-regular-expressions-in-terminal http://stackoverflow.com/questions/4794145/ Perl-One-Liner-like-grep barlop vor 9 Jahren 0

1 Antwort auf die Frage

1
Cyrus

Sed unterstützt keine nicht gierigen Übereinstimmungen, wie in ". *?" Ausdruck.

Versuche dies:

sed -nr 's/.*target name="([^"]*)" .*="(.*)".*/ * \1 - \2/p' file 

Ausgabe:

 * targetA - etwas ausgefallene Beschreibung * targetB - etwas ausgefallene Beschreibung * targetC - einige ausgefallene Beschreibung 
Scheint ein bisschen um die unsichtbare Ecke, funktioniert aber wirklich. Vielen Dank! Oliver Friedrich vor 9 Jahren 0