sed正規表現パターンは貪欲に一致したが、そうすべきではない

sed正規表現パターンは貪欲に一致したが、そうすべきではない

説明できない動作に遭遇しました。皆さんの助けがあれば幸いです。

私は、より大きなプロジェクトからある種のドキュメントを生成しようとしています。Antそのため、sed後でドキュメントに必要な情報をファイルからフィルタリングするために使用します。

次のような行を含む通常の Ant ビルドファイルがあります。

    <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">

ここで、次の sed 行を実行します。

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

次のような結果になるはずです:

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

代わりに次のようになります:

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

次の二重引用符まで正規表現を非貪欲に設定しましたが、2 番目のグループの出力をスキップして、実際に「depends」部分全体に一致するのは最初のグループであることを確認しようとしました。

ここで何が欠けているのでしょうか?

次のように、より明示的な正規表現を使用すると期待どおりに動作しますが、まだ貪欲なことはわかりません。

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

興味深いかもしれないが、私はUbuntu Linux(デフォルトインストール)でsed-4.2.2-4ubuntu1を使用している。

答え1

Sed は、「.*?」式に見られるような非貪欲一致をサポートしていません。

これを試して:

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

出力:

* targetA - ちょっとした説明
 * targetB - ちょっとした説明
 * targetC - ちょっとした説明

関連情報