web-dev-qa-db-fra.com

Comment trouver et remplacer toutes les occurrences d'une chaîne de manière récursive dans une arborescence de répertoires?

En utilisant seulement grep et sed, comment remplacer toutes les occurrences de: 

a.example.com

avec

b.example.com

dans un fichier texte de l'arborescence de répertoires /home/user/, en recherchant et en remplaçant récursivement toutes les occurrences de tous les fichiers des sous-répertoires.

44
Tony

Essaye ça:

find /home/user/ -type f | xargs sed -i  's/a.example.com/b.example.com/g'

Si vous souhaitez ignorer les répertoires de points

find . \( ! -regex '.*/\..*' \) -type f | xargs sed -i 's/a.example.com/b.example.com/g'
64
vehomzzz

Essaye ça:

grep -rl 'SearchString' ./ | xargs sed -i 's/REPLACESTRING/WITHTHIS/g'

grep -rl cherchera récursivement la SEARCHSTRING dans les répertoires ./ et remplacera les chaînes par sed.

Ex:

Remplacer un nom TOM par JERRY en utilisant la chaîne de recherche sous la forme SWATKATS dans le répertoire CARTOONNETWORK

grep -rl 'SWATKATS' CARTOONNETWORK/ | xargs sed -i 's/TOM/JERRY/g'

Ceci remplacera TOM par JERRY dans tous les fichiers et sous-répertoires sous CARTOONNETWORK à chaque fois qu'il trouvera la chaîne SWATKATS.

23
Abhinav Deshpande

Je sais que c'est une question très ancienne, mais ...

  1. La réponse de @ vehomzzz utilise find et xargs lorsque la question dit explicitement grep et sed uniquement.

  2. @EmployedRussian et @BrooksMoses ont essayé de dire que c'était un dup de awk et sed, mais ce n'est pas - encore une fois, la question dit explicitement grep et sedseulement.

Voici donc ma solution, en supposant que vous utilisiez Bash comme shell:

OLDIFS=$IFS
IFS=$'\n'
for f in `grep -rl a.example.com .` # Use -irl instead of -rl for case insensitive search
do
    sed -i 's/a\.example\.com/b.example.com/g' $f # Use /gi instead of /g for case insensitive search
done
IFS=$OLDIFS

Si vous utilisez un autre shell, tel qu'un shell, faites-le moi savoir et je vais essayer de trouver un ajustement de la syntaxe.

P.S .: Voici un one-liner:

OLDIFS=$IFS;IFS=$'\n';for f in `grep -rl a.example.com .`;do sed -i 's/a\.example\.com/b.example.com/g' $f;done;IFS=$OLDIFS

Sources:

4
Timberwolf

Pour moi, la commande suivante fonctionne:

find /path/to/dir -name "file.txt" | xargs sed -i 's/string_to_replace/new_string/g'

si la chaîne contient une barre oblique 'chemin/vers/répertoire', elle peut être remplacée par un autre caractère à séparer, comme '@' à la place '/'.

Par exemple: 's@string/to/replace@new/string@g'

1
Yahor M

Essayez cette commande:

/home/user/ directory - find ./ -type f \
-exec sed -i -e 's/a.example.com/b.example.com/g' {} \;
1
Navneet

c'est beaucoup plus simple que ça.

for i in `find *` ; do sed -i -- 's/search string/target string/g' $i;

terminé

find i => introduira tous les fichiers du dossier et des sous-dossiers dans SED.

sed -i => remplacera dans les fichiers la chaîne appropriée, si elle existe.

1
gilad 1

La commande ci-dessous recherchera tous les fichiers dont le nom correspond au modèle de recherche de manière récursive et remplacera la chaîne:

find /path/to/searchdir/ -name "serachpatter" -type f | xargs sed -i 's/stringone/StrIngTwo/g'

De plus, si vous souhaitez limiter la profondeur de la récursivité, vous pouvez également définir les limites:

find /path/to/searchdir/ -name "serachpatter" -type f -maxdepth 4 -mindepth 2 | xargs sed -i 's/stringone/StrIngTwo/g'

0
AKPrajapati