패턴과 일치하는 파일 내용을 찾고 바꾸는 방법은 무엇입니까?

패턴과 일치하는 파일 내용을 찾고 바꾸는 방법은 무엇입니까?

다음과 같은 파일이 있다고 가정합니다.프로젝트. &$ 함수가 호출될 때 패턴이 포함된 폴더의 모든 파일을 찾고 싶습니다 .

예를 들어 다음을 대체해야 합니다.

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: 여러 줄의 함수 호출 또는 정의의 두 번째 및 후속 줄에서는 변경되지 않습니다 &$. 검색 기준과 일치하지 않습니다.

모든 경우에 프로젝트 디렉터리의 작업 복사본을 만들어 사용하세요. 원하는 대로 변경되고 작동하는지 테스트한 경우(적어도 해결하는 것보다 더 많은 문제가 발생하지는 않음) 실제 프로젝트 디렉터리를 옆으로 옮기고(예: mv Project Project.old) 수정된 항목이 제자리로 이동됩니다( 예: mv Project.workingcopy Project)

관련 정보