Substitua recursivamente string em arquivos

Substitua recursivamente string em arquivos

Quero substituir a barra invertida na string page_path\example_filename.txtpor uma barra. Também quero poder executar isso em um sistema de arquivos grande e fazer com que ele pesquise recursivamente todos os diretórios.

Encontrei alguém na web que disse para usar grep, xargs, e sedmas não consegui fazê-lo funcionar. Tenho tentado diferentes variações de delimitadores e caracteres de escape, mas não consegui.

Aqui está o comando que eu estava tentando executar:
grep -lr -e 'page_path\\' * | xargs sed -i 's/page_path\/page_path//g'

Desde já, obrigado.

Responder1

Com grep | xargs, você terá problemas com espaços em branco, aspas, barras invertidas (e possivelmente mais, dependendo da xargsimplementação) em nomes de arquivos.

Com as implementações GNU de grepe xargs, você pode evitar esses problemas usando: grep -lZr ... | xargs -r0 sed ...que usa zero bytes como delimitador.

E agora com relação ao comando sed: O truque é que você pode usar s/a/b/qualquer outro caractere como separador, por exemplo s#a#b#:

sed -i 's#page_path\\#page_path/#g'

Responder2

Além disso, você pode usar find para isso:

find /your/path -type f -exec grep -l 'page_path\\' {} \; -exec sed -i 's#page_path\\#page_path/#g' {} \;

O segundo exec será executado somente se o primeiro for bem-sucedido e você não terá problemas com caracteres não imprimíveis ou que precisam de escape nos nomes dos arquivos.

Responder3

Por que desperdiçar ciclos de CPU chamando todos esses comandos quandofestacriou funcionalidade para fazer isso com MUITO menos digitação?

Exemplo

str='page_path\example_filename.txt'
echo "${str//\\/\/}"

Saída

page_path/example_filename.txt

Responder4

ripgreppode ajudar aqui também, substitua foo pelo que você deseja combinar e depois altere tanto na rginvocação quanto na sedexpressão.

rg foo --files-with-matches | xargs sed -i 's/foo/bar/g'

Se seus arquivos tiverem espaços em branco em seus nomes, diga ao ripgrep para separá-los por byte NULL

rg foo --files-with-matches -0 | xargs -0 sed -i 's/foo/bar/g'

fonte:https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#search-and-replace

informação relacionada