2

ルートディレクトリの下の複数のディレクトリにある複数のファイルで、正規表現のすべてのインスタンスを別の正規表現に置き換える必要があります。

例:ファイル構造:

.
|---src
|   |---Module
|   |   |---someclass.cpp
|   |---main.cpp
|
|---include
    |---Module
        |---someclass.hpp

基本的にはそれですが、より多くのファイルとフォルダーがあります。

正規表現を検索して、その\(std::vector<.*>すべてのインスタンスを次のように置き換える必要があります\(std::vector<.*> const& 。トリッキーな部分は、との間のコンテンツが同じであることを確認しているようです。<>

たとえば、一致して。(std::vector<int>に置き換えられ(std::vector<int> const&ます。より複雑な例は次のようになります。
一致:(std::vector<std::map<std::string, int>>
置換:(std::vector<std::map<std::string, int>> const&

4

2 に答える 2

4

例の最後の ">" が各行の最後の ">" である場合、これは機能するはずです。

find root -name '*.cpp' -print0 |
xargs -0 sed -i 's/\((std::vector<.*>\)\([^>]*$\)/\1 const\&\2/'

最初に -i を付けずに、単一のファイルで sed を試してください。

$ cat file
(std::vector<int>
(std::vector<int> foo
(std::vector<std::map<std::string, int>>
(std::vector<std::map<std::string, int>> bar

$ sed 's/\((std::vector<.*>\)\([^>]*$\)/\1 const\&\2/' file
(std::vector<int> const&
(std::vector<int> const& foo
(std::vector<std::map<std::string, int>> const&
(std::vector<std::map<std::string, int>> const& bar

例の最後のものの後に ">" がある場合、解決策は自明ではありません。代表的なサンプル入力と予想される出力を投稿してください。

なんてこった、これは重要なスクリプトです。

$ cat file
(std::vector<int>
(std::vector<int> foo
(std::vector<int> with extra > in text
(std::vector<std::map<std::string, int>>
(std::vector<std::map<std::string, int>> bar
(std::vector<std::map<std::string, int>> and here is > again

$ awk -v FS= -v str="(std::vector<" '
BEGIN{ lgth=length(str) }
start=index($0,str) {
   cnt = 1
   for(i=(start+lgth);(i<=NF) && (cnt!=0);i++) {
      if ($i == "<") cnt++
      if ($i == ">") cnt--
   }
   $0 = substr($0,1,i-1) " const&" substr($0,i)
}1' file
(std::vector<int> const&
(std::vector<int> const& foo
(std::vector<int> const& with extra > in text
(std::vector<std::map<std::string, int>> const&
(std::vector<std::map<std::string, int>> const& bar
(std::vector<std::map<std::string, int>> const& and here is > again

while ループ内でそれを行います。

find root -name '*.cpp' -print |
while IFS= read -r file; do
    awk -v FS= -v str="(std::vector<" '
    BEGIN{ lgth=length(str) }
    start=index($0,str) {
       cnt = 1
       for(i=(start+lgth);(i<=NF) && (cnt!=0);i++) {
          if ($i == "<") cnt++
          if ($i == ">") cnt--
       }
       $0 = substr($0,1,i-1) " const&" substr($0,i)
    }1' "$file" > tmp &&
    mv tmp "$file"
done

ファイル名に改行が含まれている場合は機能しませんが、改行がある場合は修正する必要があります。

于 2013-03-04T11:43:04.873 に答える
0

単純なケースと複雑なケースを、異なる正規表現で別々に処理する必要があります。正規表現では、ネストされたアイテムをカウントしてそれを説明することはできません。

ネストせずに置き換えます。\(std\:\:vector\<([^\<\>]*)\>

次に、単一のネストに置き換えます。\(std\:\:vector\<([^\<\>]*\<[^\<\>]*\>[^\<\>]*)\>

于 2013-03-04T10:45:37.613 に答える