Encontre e substitua por sed no diretório e subdiretórios


244

Eu executo este comando para encontrar e substituir todas as ocorrências de 'apple' por 'orange' em todos os arquivos na raiz do meu site:

find ./ -exec sed -i 's/apple/orange/g' {} \;

Mas não passa por subdiretórios.

O que há de errado com este comando?

Aqui estão algumas linhas de saída de find ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php

você poderia executar find ./e postar alguma saída de amostra? E a estrutura de diretórios, por favor. editar: obrigado!
27711 Jacob

Hum, sua descoberta está correta, funciona para mim com subdiretórios.
27411 Jacob

1
Como você sabe que ele não processa subdiretórios?
carlpett

porque fornece esses erros: sed: não foi possível editar ./fpd: não é um arquivo normal sed: não foi possível editar ./fpd/font: não é um arquivo regular sed: não foi possível editar ./fpd/font/makefont: não é uma regra
hd.

oh ... eu grep para apple e nada found.they todos foram substituídos. ;) obrigado . você abriu meus olhos !!!
hd.

Respostas:


421

Sua descoberta deve ser assim para evitar o envio de nomes de diretório para sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;

19
Pode ser necessário alterar sed -i 's/apple/orange/g'para sed -i '' 's/apple/orange/g'para que isso funcione.
Paulmelnikow #

7
-iusa um argumento: a extensão usada para salvar o arquivo temporário. No GNU sed, parece que não há espaço entre eles -ie seu argumento, mas no BSD sed existe ... então o BSD -i '' 's/foo/bar/'é equivalente ao GNU -i 's/foo/bar/.
22414 Paulmelnikow

20
Na verdade, a adição -enão funciona no Mac OS. touch a b c d eseguido pelo comando acima produz uma listagem como esta: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow

6
Para o Mac OS, isso responde stackoverflow.com/questions/19242275/… theRE error: illegal byte sequence
kakoma

3
Para usuários de casca de peixe, não se esqueça de citar os colchetes vazios '{}', porque o peixe expande automaticamente os colchetes vazios se não estiver entre aspas.
Kevin Cherepski

84

Para tarefas s & r maiores, é melhor e mais rápido usar grep e xargs, por exemplo;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'

20
Obrigado por esta resposta, foi muito útil! Se em um repositório git, é ainda mais rápido usandogit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues

4

Isso funcionou para mim:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;

pergunta original não restringe a arquivos .php *, há também um uma ini
knocte

O não citado *.phpestá realmente incorreto; você teve sorte de não ter sido expandido no diretório inicial porque não havia nenhum arquivo correspondente lá.
Tripleee 21/07/19

3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"

1

Como também existem pessoas do macOS lendo este (como eu fiz), o código a seguir funcionou para mim (na versão 10.14)

egrep -rl '<pattern>' <dir> | xargs -I@ sed -i '' 's/<arg1>/<arg2>/g' @

Todas as outras respostas usam -ie -enão funcionam no macOS.

Fonte


0

Acho que podemos fazer isso com um comando simples de uma linha

for i in `grep -rl eth0 . 2> /dev/null`; do sed -i ‘s/eth0/eth1/’ $i; done

Consulte esta página .


-6

No linuxOS:

sed -i 's/textSerch/textReplace/g' namefile

se "sed" não funcionar, tente:

perl -i -pe 's/textSerch/textReplace/g' namefile

4
ele quer encontrar todos os arquivos em sub-diretórios contêm essa string e substituir, e não apenas um único arquivo
phuclv
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.