Pesquisar e substituir por find e xargs não funciona

Pesquisar e substituir por find e xargs não funciona

Estou tentando pesquisar e substituir um URL presente no código-fonte de arquivos html/css na pasta e subpastas de destino. Eu tentei usar o seguinte comando:

find . -type f | xargs sed -i  's/https\:*\.websitedomain\.fr\///g'

O que estou perdendo?

Agradecemos antecipadamente por qualquer conselho

Responder1

Assumindo um sistema GNU (que seu uso sed -isugere é o seu caso):

eregex='https://[^/[:space:]]+\.websitedomain\.fr/'
find . -type f -exec grep -lZEe "$eregex" {} + |
  xargs -r0 sed -i -E "s|$eregex||g"

Alguns dos problemas em sua abordagem:

  • a principal delas é que o *operador regexp corresponda a 0 ou mais do átomo anterior, portanto :*corresponda a 0 ou mais :s. Aqui estamos substituindo-o por [^/[:space:]]+which is 1 ou more ( +, um operador regex estendido, daí os -Es) caracteres diferentes de espaço em branco e /( .*que é provavelmente o que você tinha em mente que poderia acabar correspondendo, google.com/ and foopor https://google.com/ and foo.websitedomain.fr/fileexemplo).
  • O formato de saída de find -print(um caminho de arquivo por linha) não é compatível com o formato de entrada esperado de xargs(espera palavras em branco ou separadas por nova linha, possivelmente palavras entre aspas). O formato de saída find -printnão é pós-processável de forma confiável, deve ser usado apenas para consumo humano. Melhor usar find ... -exec cmd {} +e/ou usar registros delimitados por NUL com xargs -r0( -re -0sendo extensões GNU).
  • sed -isubstitui os arquivos por uma cópia modificada do original, com possível perda de informações de metadados, por isso é melhor evitar rodar em arquivos que não serão modificados, daí o uso ou grep -lZpara obter uma lista (NUL delimitado por -Zpara que possa ser usado por xargs -0) de arquivos com pelo menos uma linha correspondente à regex.
  • :não é um operador regexp, portanto não precisa ser escapado. O que \:corresponde não é especificado pelo POSIX e não está documentado na maioria seddas implementações. Portanto, embora atualmente possa corresponder a a :em sua sedimplementação, isso pode mudar no futuro (como \<ou \wenquanto correspondia originalmente <e, wrespectivamente, acabou correspondendo a um limite de palavra e a um caractere de palavra em versões mais recentes).
  • se o seu regexp ou substituição no sedcomando scontiver um /, é mais fácil usar um caractere diferente como delimitador do que ter que escapar /com barras invertidas, o que dificulta a leitura. Portanto, s|regexp|replacement|gaqui em vez de s/regexp/replacement/g. Eu gosto |porque torna o código legível. Ele tem a desvantagem de não poder ser usado em ex/ vi's s/regex/replacement/como comandos |separados ex(também é um operador regex estendido).

Responder2

Experimente isto:

find . -type f | xargs sed -i  's/test\.com/set\.com/g' 

Se você precisar testar a inclusão dehttpsentão tente isto:

find . -type f | xargs sed -i  's/https\:\\\\test\.com/https\:\\\\set\.com/g' 

NOTA*: isto substituiteste.comcomset.com

informação relacionada