Como localizar e substituir o conteúdo dos arquivos que correspondem a um padrão?

1

Suponha que tenhamos uma pasta chamada Project . Eu gostaria de encontrar cada arquivo na pasta que contém o padrão &$ na chamada de função.

Por exemplo, deve substituir:

AnyFunction(&$arg);

com

AnyFunction($arg);

Em que AnyFunction é uma função desconhecida que corresponde ao padrão.

Eu preciso disso para tentar resolver isso problema do php .

Se possível eu também gostaria, se uma função combina com o padrão, sua declaração também muda:

function AnyFunction(&$arg)

Como posso realizar isso?

    
por GarouDan 31.08.2012 / 21:40

2 respostas

3

Uma abordagem de texto simples em que você substitui AnyFunction(arg1, &$arg2) por AnyFunction(arg1, $arg2) , a menos que precedida pela palavra function , funcionará se seu código-fonte estiver formatado de forma razoável: nenhuma declaração de função na mesma linha de uma chamada de função, sem comentários ou newline entre function e o nome da função, nenhum comentário contendo parênteses desequilibrados dentro de chamadas de função, etc. Isto irá capturar comentários e literais de string e pode perder algumas chamadas de função complicadas (por exemplo, não captura &$arg2 em f(g(), &$arg2) ).

Execute este script em seus arquivos, eles serão modificados no lugar. Aviso: não testado, faça backups primeiro!

#!/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
    
por 01.09.2012 / 04:42
2

Esta é uma pesquisa bastante direta e substitua por sed.

  1. o caso mais simples, se você puder ter certeza de que não há outras instâncias de &$ que você não deseja alterar:

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

  2. Como acima, mas restringindo a pesquisa e substituição apenas ao primeiro argumento de uma chamada ou definição de função (como no seu exemplo acima):

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

  3. Como em 1. acima, mas restringindo a substituição a linhas em que & $ é encontrado entre parênteses:

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

    note1: isso ainda irá alterar qualquer outro &$ na mesma linha que esteja fora dos parênteses, mas apenas nas linhas onde ele já foi encontrado dentro dos parênteses (...&$...)

    note2: isso não alterará &$ na segunda linha e nas linhas subsequentes de chamadas de função com várias linhas ou definições ... elas não correspondem aos critérios de pesquisa.

Em todos os casos, crie uma cópia de trabalho do seu diretório do Project e trabalhe com ela. Quando é alterado para o que você quer, e você testou que funciona (pelo menos sem introduzir mais problemas do que resolve), mova o diretório real do Projecto para o lado (por exemplo, mv Project Project.old ) e mova o Projeto modificado para o lugar (por exemplo mv Project.workingcopy Project )

    
por 01.09.2012 / 04:16