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

¿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' {} \;

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'

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 {} \;

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|"

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


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 .


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.