パターンに一致するファイルの内容を見つけて置き換える方法は?

パターンに一致するファイルの内容を見つけて置き換える方法は?

次のファイルがあるとします。プロジェクト&$ 関数が呼び出されたときにパターンを含むフォルダ内のすべてのファイルを検索したいと思います。

たとえば、次のものを置き換える必要があります。

AnyFunction(&$arg);

そして

AnyFunction($arg);

AnyFunctionパターンに一致する未知の関数はどこにありますか?

この問題を解決するにはこれが必要です。PHPの問題

可能であれば、関数がパターンと一致する場合、その宣言も変更されることを願っています。

function AnyFunction(&$arg)

どうすればいいですか?

答え1

ソースコードの形式が正しい場合、単語が前に来ない限り、単純なテキストアプローチが機能します。AnyFunction(arg1, &$arg2)関数呼び出しと同じ行に関数宣言がなく、関数名の間にコメントや改行がなく、関数呼び出し内の括弧の周りにバランスのとれたコメントは含まれません。 、等。これにより、コメントと文字列リテラルをキャプチャし、いくつかの複雑な関数呼び出しを見逃すことがあります(たとえば、キャプチャできません)。AnyFunction(arg1, $arg2)functionfunction&$arg2f(g(), &$arg2)

ファイルからこのスクリプトを実行すると、その場所で変更されます。警告:テストされていません。まずバックアップしてください!

#!/usr/bin/perl -pi
BEGIN { use warnings; use strict; undef $/; }
sub straighten_ampersands {
    my ($args, $want_ampersands) = @_;
    $want_ampersands = ($want_ampersands ? "&" : "");
    $args =~ s{ ([(,]\s*) &? (\$\w) }
              { $1 $want_ampersands $2 }x;
}
s{
  (\bfunction\s+|)(\w+\s+)      # optional 'function' keyword, then function name
  (\((?:(?>[^()]+)|(?4))*)\)))  # balanced parentheses (from perlre)
 }{
  "$1$2" . straighten_ampersands($3, $1 ne "")
 }ex

答え2

これは非常に簡単な検索で、sedに置き換えられます。

  1. &$最も簡単な場合は、変更したくない他のインスタンスがないと確信できる場合です。

    find Project -name '*.php' -print0 | xargs -0r sed -i -e 's/&\$/$/g'

  2. 上記と同じですが、検索と置換を関数呼び出しまたは定義の最初の引数に制限します(上記の例のように)。

    find Project -name '*.php' -print0 | xargs -0r sed -i -e 's/(&\$/($/g'

  3. 上記の1.と同じですが、括弧内に&$が表示される行に置き換えを制限します。

    find Project -name '*.php' -print0 | xargs -0r sed -i -e '/([^)]*&\$[^)]*)/ s/&\$/$/g'

    &$注1:これにより、同じ行にある括弧以外の内容はまだ変更されますが、括弧内に既にある行にのみ適用されます。(...&$...)

    注2:複数行の関数呼び出しまたは定義の2行目以降の行では変更されません&$。検索条件と一致しません。

すべての場合で、プロジェクトディレクトリの作業コピーを作成して使用してください。必要に応じて変更され動作するかどうかをテストした場合(少なくとも解決するよりも多くの問題は発生しません)、実際のプロジェクトディレクトリを横に移動し(例:)、変更されたmv Project Project.old項目が所定の位置に移動されます(例:mv Project.workingcopy Project) 。

関連情報