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 -i
sugere é 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-E
s) caracteres diferentes de espaço em branco e/
(.*
que é provavelmente o que você tinha em mente que poderia acabar correspondendo,google.com/ and foo
porhttps://google.com/ and foo.websitedomain.fr/file
exemplo). - O formato de saída de
find -print
(um caminho de arquivo por linha) não é compatível com o formato de entrada esperado dexargs
(espera palavras em branco ou separadas por nova linha, possivelmente palavras entre aspas). O formato de saídafind -print
não é pós-processável de forma confiável, deve ser usado apenas para consumo humano. Melhor usarfind ... -exec cmd {} +
e/ou usar registros delimitados por NUL comxargs -r0
(-r
e-0
sendo extensões GNU). sed -i
substitui 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 ougrep -lZ
para obter uma lista (NUL delimitado por-Z
para que possa ser usado porxargs -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 maioriased
das implementações. Portanto, embora atualmente possa corresponder a a:
em suased
implementação, isso pode mudar no futuro (como\<
ou\w
enquanto correspondia originalmente<
e,w
respectivamente, 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
sed
comandos
contiver 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|g
aqui em vez des/regexp/replacement/g
. Eu gosto|
porque torna o código legível. Ele tem a desvantagem de não poder ser usado emex
/vi
'ss/regex/replacement/
como comandos|
separadosex
(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