Rechercher et remplacer par sed dans les répertoires et sous-répertoires

244

J'exécute cette commande pour trouver et remplacer toutes les occurrences de 'apple' par 'orange' dans tous les fichiers à la racine de mon site:

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

Mais il ne passe pas par les sous-répertoires.

Quel est le problème avec cette commande?

Voici quelques lignes de sortie de find ./:

./index.php
./header.php
./fpd
./fpd/font
./fpd/font/desktop.ini
./fpd/font/courier.php
./fpd/font/symbol.php
HD.
la source
pourriez-vous exécuter find ./et publier un exemple de sortie? Et la structure du répertoire s'il vous plaît. modifier: merci!
Jacob
Hm votre trouvaille est correcte, fonctionne pour moi avec des sous-répertoires.
Jacob
1
Comment savez-vous qu'il ne traite pas les sous-répertoires?
carlpett
car il donne ces erreurs: sed: impossible d'éditer ./fpd: pas un fichier normal sed: impossible d'éditer ./fpd/font: pas un fichier normal sed: impossible d'éditer ./fpd/font/makefont: pas un regula
hd.
oh ... je convoite pour apple et rien trouvé.ils ont tous été remplacés. ;) Je vous remercie . tu m'as ouvert les yeux !!!
hd.

Réponses:

423

Votre recherche devrait ressembler à cela pour éviter d'envoyer des noms de répertoire à sed:

find ./ -type f -exec sed -i -e 's/apple/orange/g' {} \;
jfg956
la source
19
Vous devrez peut - être changer sed -i 's/apple/orange/g'pour sed -i '' 's/apple/orange/g'faire ce travail.
paulmelnikow
7
-iprend un argument: l'extension utilisée pour enregistrer le fichier temporaire. Dans GNU sed, il semble qu'il n'y ait pas d'espace entre -iet son argument, mais dans BSD sed il y en a… donc BSD -i '' 's/foo/bar/'est équivalent à GNU -i 's/foo/bar/.
paulmelnikow
20
En fait, l'ajout -ene fonctionne pas sur Mac OS. touch a b c d esuivi de la commande produit liste ci - dessus un répertoire comme celui - ci: a a-e b b-e c c-e d d-e e e-e.
paulmelnikow
6
Pour Mac OS, cela répond à stackoverflow.com/questions/19242275/… leRE error: illegal byte sequence
kakoma
3
Pour les utilisateurs de coquille de poisson, assurez-vous de citer les accolades vides '{}', car le poisson étend automatiquement les accolades vides s'il n'est pas cité.
Kevin Cherepski
86

Pour les tâches s & r plus importantes, il est préférable et plus rapide d'utiliser grep et xargs, par exemple;

grep -rl 'apples' /dir_to_search_under | xargs sed -i 's/apples/oranges/g'
Julius
la source
20
Merci pour cette réponse, cela a été très utile! Si dans un dépôt git, c'est encore plus rapide à utilisergit grep -l 'apples' | xargs sed -i 's/apples/oranges/g'
mrodrigues
4

Cela a fonctionné pour moi:

find ./ -type f -exec sed -i '' 's#NEEDLE#REPLACEMENT#' *.php {} \;
Blackdad
la source
la question d'origine ne se limite pas aux fichiers * .php, il y en a aussi une .ini
knocte
Le non cité *.phpest vraiment incorrect; vous avez juste eu de la chance qu'il n'ait pas été développé dans le répertoire de départ car il n'y avait aucun fichier correspondant.
tripleee
3
grep -e apple your_site_root/**/*.* -s -l | xargs sed -i "" "s|apple|orage|"
rocLv
la source
1

Puisqu'il y a aussi des gens macOS qui lisent celui-ci (comme je l'ai fait), le code suivant a fonctionné pour moi (le 10.14)

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

Toutes les autres réponses utilisant -iet -ene fonctionnent pas sur macOS.

La source

pat-s
la source
0

Je pense que nous pouvons le faire avec une simple commande en ligne

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

Reportez-vous à cette page .

Sukrant
la source
-6

Sous linuxOS:

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

si "sed" ne fonctionne pas, essayez:

perl -i -pe 's/textSerch/textReplace/g' namefile
ฉัตร ชัย สิทธิ วง ค์
la source
4
il veut trouver tous les fichiers dans les sous-répertoires contiennent cette chaîne et remplacer, pas seulement un seul fichier
phuclv