Comando SED não substituindo (regex funcionando)

Comando SED não substituindo (regex funcionando)

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

Ex:

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

Consigo capturar tudo (de acordo com o testador Regex), mas nada parece ter sido substituído e nenhum erro também.

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

Eu li sobre barras invertidas emsedmas não entendi direito; a saída não contém erros, mas o arquivo permanece o mesmo. Se eu pudesse saber 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. Estou usando um arquivo temporário apenas para ter certeza de que funciona antes de testá-lo em meu projeto.

Obrigado.

EDITAR: Eu sei que se quiser fazer tudo de uma vez, tenho que capturarmysqlpor conta própria e adicione umeu, mas isso foi apenas um pensamento.


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

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

Glenn sugeriu uma solução sem captura. No entanto, se eu quiser modificarmysql_fetch_array($consulta), então talvez eu precise usar regex para manter o primeiro parâmetro e anexarMYSQLI_BOTHpor exemplo.


SOLUÇÃO:

Graças ao tedron, consegui resolver meu problema do meu jeito:

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

E para mysqli_fetch_array:

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

Use isso grepcomo fiz na minha pergunta para modificar um diretório de uma vez.

Responder1

Você não precisa capturar nada:

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

Não use -ienquanto estiver testando; adicione quando estiver satisfeito com os resultados.

Responder2

Ainda outra possibilidade usando regexp estendido ( -r):

sed -r 's/(mysql)(_query\()/\1i\2$link,/g'

Responder3

Você não precisa de um grupo de captura mysql_query, porque não o está copiando para o substituto. Você só precisa capturar o argumento da consulta, pois isso varia em cada chamada.

sed -ri 's/mysql_query\s*\((\$\w+)\)/mysqli_query($link, \1)/g'

Responder4

O problema é o \w. Eu só descobri isso quando tentei descobrir o que está acontecendo aqui, mas aparentemente, coisas como \sou \wque já são classes de personagens não podem ser usadas dentro de outras classes de personagens com ERE (podem com PCREs). 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-

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

Para fazer sua expressão regular funcionar, use parênteses [a-zA-z_]em vez de \wou 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_-]+)\)/\1($link,\2)/'
mysql_query($link,$query)

informação relacionada