O comando SED não está sendo substituído (regex em funcionamento)

2

Estou tentando substituir em um dos meus projetos todos os mysql para mysqli , com seus parâmetros. Para fazer isso, estou procurando por todos os arquivos com mysql na minha pasta recursivamente e substituindo-os pelo mysqli.

Ex:

mysql_query($query) to mysqli_query($link, $query)

Eu sou capaz de capturar tudo (de acordo com o testador Regex), mas nada parece ser substituído, e também não há erros.

grep -rl mysql PROJECTFILE | xargs sed -ri "s/(mysql_query)\(\$([\w-]+)\)/WhatIWant/g"

Eu li sobre barras invertidas em sed mas não entendi bem; a saída não tem erros, mas o arquivo permanece o mesmo. Se eu puder saber apenas o que está faltando com um exemplo ou explicação, isso seria perfeito.

É fácil substituir o mysql pelo mysqli, mas seria bom fazer tudo de uma vez. Eu estou usando um arquivo temporário só para ter certeza de que funciona antes que eu possa experimentá-lo no meu projeto.

Obrigado.

EDIT : Eu sei que se eu quiser fazer tudo de uma vez eu tenho que capturar o mysql sozinho e adicionar um i , mas isso foi apenas um pensamento.

Para o tedron, minha saída desejada seria semelhante a isso.

sed -ri "s/(mysql_query)\(\$([\w-]+)\)/mysqli_query($link, )/g" filename

glenn sugeriu uma solução sem captura. No entanto, se eu quiser modificar mysql_fetch_array ($ query) , então eu posso ter que usar o regex para manter o primeiro parâmetro e acrescentar MYSQLI_BOTH por exemplo.

SOLUÇÃO:

Graças ao tedron, consegui resolver o meu problema da seguinte maneira:

sed -ri 's/(mysql)_query\((\$[a-zA-Z_-]+)\)/i_query($link, )/' filename

E para mysqli_fetch_array:

sed -ri 's/(mysql)(_fetch_array)\((\$[a-zA-Z_-]+)\)/i(, MYSQLI_BOTH)/' filename

Use isso com grep como eu fiz na minha pergunta para modificar um diretório de uma só vez.

    
por Atieh 17.11.2014 / 22:51

4 respostas

0

O problema é o \w . Eu só descobri isso ao tentar descobrir o que está acontecendo aqui, mas aparentemente, coisas como \s ou \w que já são classes de caracteres não podem ser usadas dentro de outras classes de caracteres com ERE (podem com PCREs). Para ilustrar:

$ echo foo- | sed -r 's/[\w-]+/bar/'
foobar
$ echo 'w\-foo' | sed -r 's/[\w-]+/bar/'
barfoo
$ echo foo- | sed -r 's/\w+/bar/'
bar-

Assim, as classes de escape de caracteres são tratadas como caracteres literais quando dentro de uma classe de caracteres [ ] . A expressão [\w-] significa "corresponde a qualquer um dos \ , w ou - .

Para fazer sua expressão regular funcionar, use [a-zA-z_] em vez de \w ou use parênteses de agrupamento:

$ echo 'mysql_query($query)' | 
    sed -r 's/mysql_query\(\$(\w|-)+\)/WhatIWant/'
WhatIWant

Especificamente para o seu exemplo:

$ echo 'mysql_query($query)' | 
    sed -r 's/(mysql_query)\((\$[a-zA-Z_-]+)\)/($link,)/'
mysql_query($link,$query)
    
por 18.11.2014 / 21:39
6

Você não precisa capturar nada:

sed 's/mysql_query(/mysqli_query($link, /g' file

Não use -i enquanto estiver testando, adicione isso quando estiver satisfeito com os resultados.

    
por 17.11.2014 / 23:01
2

Ainda outra possibilidade usando o regexp estendido ( -r ):

sed -r 's/(mysql)(_query\()/i$link,/g'
    
por 17.11.2014 / 23:51
1

Você não precisa de um grupo de captura em torno de mysql_query , porque você não está copiando isso para a substituição. Você só precisa capturar o argumento da consulta, já que isso varia em cada chamada.

sed -ri 's/mysql_query\s*\((\$\w+)\)/mysqli_query($link, )/g'
    
por 17.11.2014 / 23:01