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

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

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'

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

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

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


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 .


-6

Sous linuxOS:

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

si "sed" ne fonctionne pas, essayez:

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

4
il veut trouver tous les fichiers dans les sous-répertoires contiennent cette chaîne et remplacer, pas seulement un seul fichier
phuclv
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.