Buscar y reemplazar con sed en el directorio y subdirectorios

244

Ejecuto este comando para buscar y reemplazar todas las apariciones de 'apple' con 'orange' en todos los archivos en la raíz de mi sitio:

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

Pero no pasa por subdirectorios.

¿Qué hay de malo con este comando?

Aquí hay algunas líneas de salida de find ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
hd.
fuente
¿podría ejecutar find ./y publicar algunos resultados de muestra? Y la estructura del directorio por favor. editar: gracias!
Jacob
Hm tu hallazgo es correcto, funciona para mí con subdirectorios.
Jacob
1
¿Cómo sabes que no procesa subdirectorios?
carlpett
porque da estos errores: sed: no se pudo editar ./fpd: no es un archivo normal sed: no se pudo editar ./fpd/font: no es un archivo normal sed: no se pudo editar ./fpd/font/makefont: no es un regulador
hd.
oh ... busqué manzana y no encontré nada. Todos fueron reemplazados. ;) gracias . abriste mis ojos !!!
hd.

Respuestas:

421

Su hallazgo debería verse así para evitar enviar nombres de directorio a sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
jfg956
fuente
19
Es posible que deba cambiar sed -i 's/apple/orange/g'a sed -i '' 's/apple/orange/g'para que esto funcione.
paulmelnikow
77
-itoma un argumento: la extensión utilizada para guardar el archivo temporal. En GNU sed, parece que no hay espacio entre -iy su argumento, pero en BSD sed sí existe ... entonces BSD -i '' 's/foo/bar/'es equivalente a GNU -i 's/foo/bar/.
paulmelnikow
20
Agregar realmente -eno funciona en Mac OS. touch a b c d eseguido por el comando anterior produce un listado del directorio de esta manera: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow
66
Para Mac OS, esto responde stackoverflow.com/questions/19242275/… theRE error: illegal byte sequence
kakoma
3
Para los usuarios de conchas de pescado, asegúrese de citar las llaves vacías '{}', ya que fish expande automáticamente las llaves vacías si no se cita.
Kevin Cherepski
84

Para tareas de s & r más grandes, es mejor y más rápido usar grep y xargs, por ejemplo;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Julius
fuente
20
Gracias por esta respuesta, ¡fue muy útil! Si está en un repositorio de git, es aún más rápido usargit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues el
4

Esto funcionó para mí:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
blackdad
fuente
la pregunta original no se restringe a los archivos * .php, también hay una .ini
tocada el
Lo que no *.phpse cita es realmente incorrecto; Tuviste suerte de que no se expandiera en el directorio de inicio porque no tenías ningún archivo coincidente allí.
tripleee
3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"
rocLv
fuente
1

Como también hay personas de macOS que leen este (como lo hice), el siguiente código funcionó para mí (el 10.14)

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

Todas las demás respuestas usan -iy -eno funcionan en macOS.

Fuente

pat-s
fuente
0

Creo que podemos hacer esto con un comando simple de una línea

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

Consulte esta página .

Sukrant
fuente
-6

En linuxOS:

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

si "sed" no funciona, intente:

perl -i -pe 's/textSerch/textReplace/g' namefile
ฉัตร ชัย สิทธิ วง ค์
fuente
44
quiere encontrar todos los archivos en los subdirectorios contienen esa cadena y reemplazar, no sólo un único archivo
phuclv