1

私は次のコードレイアウトを持っています:

#ifndef _file_h_
#define _file_h_

namespace FooBar
{
    // code
}

#endif

これを sed で実行し、FooBar 名前空間を Foo::Bar に変換し、右中括弧を追加したい

#ifndef _file_h_
#define _file_h_

namespace Foo { namespace Bar {

// code

}}

#endif

私の正規表現の知識は、最良の場合でも非常に貧弱であることを認めます。

以下のコマンドは、探しているものを達成するのに近いと思いますが、構文の一部が間違っています。誰か助けてくれませんか?

cat file.h  | sed -e 's/(.*)namespace FooBar[\s\n]{(.*)}/\1namesapce Foo \{ namespace Bar \{\2\}\}/g' | less
4

2 に答える 2

1

最後のブレースが常にファイルの最後のブレースになることを知っていると、うまくいくかもしれないという考えが得られます。

まず、Rob の最初の正規表現を盗みます。

sed -ie 's/namespace FooBar/namespace Foo { namespace Bar/g;' file.h

次に、最後のブレースの新しい正規表現:

perl -pi -e 's/^}$(.*?)\z/}}\1/ms' file.h

2 番目のコマンドを Perl に切り替えたので、あまり欲張らない*?演算子である^and$\zアサーション、および/ms修飾子 (使いやすい複数行の一致を得るため) を使用できました。

これら 2 つのコマンドを組み合わせると、サンプル ファイルが次のように変更されます。

$ diff -u file.h.backup file.h
--- file.h.backup   2012-05-21 16:27:29.000000000 -0700
+++ file.h  2012-05-21 16:29:31.000000000 -0700
@@ -1,10 +1,10 @@
 #ifndef _file_h_
 #define _file_h_

-namespace FooBar
+namespace Foo { namespace Bar
 {
     // code
-}
+}}

 #endif

これ非常に脆弱です。完全な C++ 言語パーサーははるかに堅牢ですが、これほど簡単に書くことはできません。残ったものは手で簡単に処理できるといいのですが。

于 2012-05-21T23:33:55.900 に答える
1

うまくいけば、ヘッダーファイルのフォーマットは常にあなたが示したようなものです(独自の行の名前空間、行頭の開き括弧/閉じ括弧など)。

その場合は、ここでのキャプチャについて心配する必要はありません。試す:

sed -e 's/namespace FooBar/namespace Foo { namespace Bar/g; s/^}/}}/g;' file.h > file2.h

そうでない場合は、@sarnold のコメントを心に留めておいてください - これは難しいでしょう。

于 2012-05-21T23:17:54.987 に答える